Test Failed
Pull Request — master (#17)
by Denis
10:14
created

QueryFilterTest::testAliases()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 63
Code Lines 50

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 50
nc 1
nop 0
dl 0
loc 63
rs 9.0909
c 0
b 0
f 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 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
        $this->expectException(UnexpectedValueException::class);
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
        $this->expectException(UnexpectedValueException::class);
168
        $this->expectExceptionMessage('Invalid filter column requested t.unknownColumn');
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
        $this->expectException(UnexpectedValueException::class);
197
        $this->expectExceptionMessage('Invalid filter column requested [1]');
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
267
                // will be ignored
268
                [
269
                    'field' => 't.unknownColumn',
270
                    'type' => 'eq',
271
                    'x' => 'the road to hell'
272
                ]
273
            ],
274
        ]));
275
        $config->setRequest($request);
276
        $config->setSearchAllowedCols(['t.knownColumn']);
277
        $config->setStrictColumns(false);
278
279
        $config->setRepositoryCallback(function(QueryFilterArgs $args) {
280
            self::assertEquals([
281
                (new Filter())
282
                    ->setField('t.knownColumn')
283
                    ->setType('eq')
284
                    ->setX('shla sasha po shosse i sosala sushku'),
285
            ], $args->getSearchBy());
286
            return new QueryResult([
287
                ["dummy"],
288
                ["wammy"],
289
            ], 1000);
290
        });
291
        $response = $queryFilter->getData($config);
292
        self::assertEquals([
293
            ["dummy"],
294
            ["wammy"],
295
        ], $response->getData());
296
    }
297
298
    public function testGetDataInvalidFullFilterFormatWithoutThrow()
299
    {
300
        $queryFilter = new QueryFilter(Response::class);
301
302
        $config = new BaseConfig();
303
        $request = new Request(new HttpRequest([
304
            'simple' => 0,
305
            'filter' => [
306
                [
307
                    'field' => 't.knownColumn',
308
                    'type' => 'eq',
309
                    'x' => 'shla sasha po shosse i sosala sushku'
310
                ],
311
                't.unknownColumn', // will be ignored
312
            ],
313
        ]));
314
        $config->setRequest($request);
315
        $config->setSearchAllowedCols(['t.knownColumn']);
316
        $config->setStrictColumns(false);
317
318
        $config->setRepositoryCallback(function(QueryFilterArgs $args) {
319
            self::assertEquals([
320
                (new Filter())
321
                    ->setField('t.knownColumn')
322
                    ->setType('eq')
323
                    ->setX('shla sasha po shosse i sosala sushku'),
324
            ], $args->getSearchBy());
325
            return new QueryResult([
326
                ["dummy"],
327
                ["wammy"],
328
            ], 1000);
329
        });
330
        $response = $queryFilter->getData($config);
331
        self::assertEquals([
332
            ["dummy"],
333
            ["wammy"],
334
        ], $response->getData());
335
    }
336
337
    public function testGetDataInvalidRepositoryCallback()
338
    {
339
        $this->expectException(MissingArgumentException::class);
340
        $this->expectExceptionMessage('Repository callback is not set');
341
        $queryFilter = new QueryFilter(Response::class);
342
343
        $config = new BaseConfig();
344
        $request = new Request(new HttpRequest([
345
            'simple' => 0,
346
            'filter' => [
347
                [
348
                    'field' => 't.knownColumn',
349
                    'type' => 'eq',
350
                    'x' => 'shla sasha po shosse i sosala sushku'
351
                ],
352
            ],
353
        ]));
354
        $config->setRequest($request);
355
        $config->setSearchAllowedCols(['t.knownColumn']);
356
        $queryFilter->getData($config);
357
    }
358
359
    public function testGetDataInvalidSortColumn()
360
    {
361
        $this->expectException(UnexpectedValueException::class);
362
        $this->expectExceptionMessage('Invalid sort column requested c.invalidColumn');
363
        $queryFilter = new QueryFilter(Response::class);
364
365
        $config = new BaseConfig();
366
        $request = new Request(new HttpRequest([
367
            'sortby' => 'c.invalidColumn',
368
            'sortdir' => 'asc',
369
        ]));
370
        $config->setRequest($request);
371
        $config->setSortCols(['c.id']);
372
        $config->setStrictColumns(true);
373
374
        $queryFilter->getData($config);
375
    }
376
377
    public function testGetDataInvalidSortColumnType()
378
    {
379
        $this->expectException(UnexpectedValueException::class);
380
        $this->expectExceptionMessage('Invalid sort type requested to_the_left');
381
        $queryFilter = new QueryFilter(Response::class);
382
383
        $config = new BaseConfig();
384
        $request = new Request(new HttpRequest([
385
            'sortby' => 'c.id',
386
            'sortdir' => 'to_the_left',
387
        ]));
388
        $config->setRequest($request);
389
        $config->setSortCols(['c.id']);
390
        $config->setStrictColumns(true);
391
392
        $queryFilter->getData($config);
393
    }
394
395
    public function testGetDataAdvancedBaseCase()
396
    {
397
        $queryFilter = new QueryFilter(Response::class);
398
399
        $config = new BaseConfig();
400
        $request = new Request(new HttpRequest([
401
            'limit' => 100,
402
            'page'=> 3,
403
            'filter' => [
404
                [
405
                    'field' => 'c.hell',
406
                    'type' => 'eq',
407
                    'x' => 'the road to hell',
408
                ],
409
                [
410
                    'field' => 'c.heaven',
411
                    'type' => 'like',
412
                    'x' => 'the road to heaven',
413
                ],
414
                [
415
                    'field' => 'c.latency',
416
                    'type' => 'between',
417
                    'x' => '10',
418
                    'y' => '100',
419
                ],
420
                [
421
                    'field' => 'c.hell',
422
                    'type' => 'like',
423
                    'x' => 'the road to hell',
424
                    'connector' => 'or',
425
                    'extra' => 'exact',
426
                ],
427
            ],
428
            'sortby' => 'c.id',
429
            'sortdir' => 'asc',
430
            'simple' => '0',
431
        ]));
432
        $config->setRequest($request);
433
        $config->setSearchAllowedCols(['c.hell', 'c.heaven', 'c.latency']);
434
        $config->setSortCols(['c.id']);
435
        $config->setAllowedLimits([10, 15, 100]);
436
        $config->setDefaultLimit(10);
437
438
        $config->setRepositoryCallback(function(QueryFilterArgs $args) {
439
            self::assertSame(100, $args->getLimit());
440
            self::assertSame(200, $args->getOffset());
441
            self::assertEquals([
442
                (new Filter())
443
                    ->setField('c.hell')
444
                    ->setType('eq')
445
                    ->setX('the road to hell'),
446
                (new Filter())
447
                    ->setField('c.heaven')
448
                    ->setType('like')
449
                    ->setX('the road to heaven'),
450
                (new Filter())
451
                    ->setField('c.latency')
452
                    ->setType('between')
453
                    ->setX('10')
454
                    ->setY('100'),
455
                (new Filter())
456
                    ->setField('c.hell')
457
                    ->setType('like')
458
                    ->setX('the road to hell')
459
                    ->setExtra('exact')
460
                    ->setConnector('or')
461
            ], $args->getSearchBy());
462
            self::assertEquals([
463
                'c.id' => 'asc',
464
            ], $args->getSortBy());
465
466
            return new QueryResult([
467
                ["dummy"],
468
                ["wammy"],
469
            ], 1000);
470
        });
471
        $response = $queryFilter->getData($config);
472
        self::assertEquals([
473
            ["dummy"],
474
            ["wammy"],
475
        ], $response->getData());
476
        self::assertSame(1000, $response->getMeta()['total_records']);
477
    }
478
479
    public function testAliases()
480
    {
481
        $queryFilter = new QueryFilter(Response::class);
482
483
        $config = new BaseConfig();
484
        $request = new Request(new HttpRequest([
485
            'limit' => 100,
486
            'page'=> 3,
487
            'filter' => [
488
                [
489
                    'field' => 'fullname',
490
                    'type' => 'eq',
491
                    'x' => 'Vassily Poupkine',
492
                    'having' => '1',
493
                ],
494
                [
495
                    'field' => 'c.heaven',
496
                    'type' => 'like',
497
                    'x' => 'the road to heaven',
498
                ],
499
            ],
500
            'sortby' => 'c.id',
501
            'sortdir' => 'asc',
502
            'simple' => '0',
503
        ]));
504
        $config->setRequest($request);
505
        $config->setSearchAllowedCols(['fullname', 'c.heaven']);
506
        $config->setSortCols(['c.id']);
507
        $config->setAllowedLimits([10, 15, 100]);
508
        $config->setDefaultLimit(10);
509
        $config->setSearchByAliases([
510
            (new Alias('fullname', 'concat(\'c.firstname, \' \', c.lastname\')'))
511
        ]);
512
513
        $config->setRepositoryCallback(function(QueryFilterArgs $args) {
514
            self::assertSame(100, $args->getLimit());
515
            self::assertSame(200, $args->getOffset());
516
            self::assertEquals([
517
                (new Filter())
518
                    ->setField('concat(\'c.firstname, \' \', c.lastname\')')
519
                    ->setType('eq')
520
                    ->setX('Vassily Poupkine')
521
                    ->setHaving(true),
522
                (new Filter())
523
                    ->setField('c.heaven')
524
                    ->setType('like')
525
                    ->setX('the road to heaven'),
526
            ], $args->getSearchBy());
527
            self::assertEquals([
528
                'c.id' => 'asc',
529
            ], $args->getSortBy());
530
531
            return new QueryResult([
532
                ["dummy"],
533
                ["wammy"],
534
            ], 1000);
535
        });
536
        $response = $queryFilter->getData($config);
537
        self::assertEquals([
538
            ["dummy"],
539
            ["wammy"],
540
        ], $response->getData());
541
        self::assertSame(1000, $response->getMeta()['total_records']);
542
    }
543
}
544