Completed
Push — develop ( d7f07d...880ad5 )
by Abdelrahman
03:03
created

EloquentRepositoryCriteriaTests   A

Complexity

Total Complexity 29

Size/Duplication

Total Lines 471
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 4

Importance

Changes 0
Metric Value
dl 0
loc 471
c 0
b 0
f 0
wmc 29
lcom 1
cbo 4
rs 10
1
<?php
2
3
class EloquentRepositoryCriteriaTests extends AbstractEloquentTests
4
{
5
    public function testObjectCriterionPush()
6
    {
7
        $userRepository = $this->userRepository();
8
        $criterion      = new FirstTestCriterion();
9
        $userRepository->pushCriterion($criterion);
10
11
        $this->assertAttributeCount(1, 'criteria', $userRepository);
12
        $this->assertAttributeContains($criterion, 'criteria', $userRepository);
13
    }
14
15
    public function testClosureCriterionPush()
16
    {
17
        $userRepository = $this->userRepository();
18
        $criterion      = function ($query, $repository) {
19
            return $query->where('id', 1);
20
        };
21
22
        $userRepository->pushCriterion($criterion);
23
24
        $this->assertAttributeCount(1, 'criteria', $userRepository);
25
        $this->assertAttributeContains($criterion, 'criteria', $userRepository);
26
    }
27
28
    public function testClassNameCriterionPush()
29
    {
30
        $userRepository = $this->userRepository();
31
        $criterion      = FirstTestCriterion::class;
32
        $userRepository->pushCriterion($criterion);
33
34
        $this->assertAttributeCount(1, 'criteria', $userRepository);
35
        $this->assertContainsOnlyInstancesOf($criterion, $this->getObjectAttribute($userRepository, 'criteria'));
36
    }
37
38
    public function testClassNameWithAssocArgumentsAssocCriterionPush()
39
    {
40
        $userRepository = $this->userRepository();
41
        $userRepository->pushCriterion([ThirdTestWithArgumentsCriterion::class => ['to' => '2016-09-30', 'from' => '2016-09-01']]);
42
43
        $this->assertAttributeCount(1, 'criteria', $userRepository);
44
        $this->assertArrayHasKey(ThirdTestWithArgumentsCriterion::class, $userRepository->getCriteria());
45
46
        $criterion = $userRepository->getCriterion(ThirdTestWithArgumentsCriterion::class);
47
        $this->assertAttributeEquals('2016-09-01', 'from', $criterion);
48
        $this->assertAttributeEquals('2016-09-30', 'to', $criterion);
49
    }
50
51
    public function testClassNameWithAssocArgumentsSequentialCriterionPush()
52
    {
53
        $userRepository = $this->userRepository();
54
        $userRepository->pushCriterion([ThirdTestWithArgumentsCriterion::class, ['to' => '2016-09-30', 'from' => '2016-09-01']]);
55
56
        $this->assertAttributeCount(1, 'criteria', $userRepository);
57
        $this->assertArrayHasKey(ThirdTestWithArgumentsCriterion::class, $userRepository->getCriteria());
58
59
        $criterion = $userRepository->getCriterion(ThirdTestWithArgumentsCriterion::class);
60
        $this->assertAttributeEquals('2016-09-01', 'from', $criterion);
61
        $this->assertAttributeEquals('2016-09-30', 'to', $criterion);
62
    }
63
64
    public function testClassNameWithSequentialArgumentsAssocCriterionPush()
65
    {
66
        $userRepository = $this->userRepository();
67
        $userRepository->pushCriterion([ThirdTestWithArgumentsCriterion::class => ['2016-09-01', '2016-09-30']]);
68
69
        $this->assertAttributeCount(1, 'criteria', $userRepository);
70
        $this->assertArrayHasKey(ThirdTestWithArgumentsCriterion::class, $userRepository->getCriteria());
71
72
        $criterion = $userRepository->getCriterion(ThirdTestWithArgumentsCriterion::class);
73
        $this->assertAttributeEquals('2016-09-01', 'from', $criterion);
74
        $this->assertAttributeEquals('2016-09-30', 'to', $criterion);
75
    }
76
77
    public function testClassNameWithSequentialArgumentsSequentialCriterionPush()
78
    {
79
        $userRepository = $this->userRepository();
80
        $userRepository->pushCriterion([ThirdTestWithArgumentsCriterion::class, ['2016-09-01', '2016-09-30']]);
81
82
        $this->assertAttributeCount(1, 'criteria', $userRepository);
83
        $this->assertArrayHasKey(ThirdTestWithArgumentsCriterion::class, $userRepository->getCriteria());
84
85
        $criterion = $userRepository->getCriterion(ThirdTestWithArgumentsCriterion::class);
86
        $this->assertAttributeEquals('2016-09-01', 'from', $criterion);
87
        $this->assertAttributeEquals('2016-09-30', 'to', $criterion);
88
    }
89
90
    public function testPushTwoDifferentCriteria()
91
    {
92
        $userRepository  = $this->userRepository();
93
        $firstCriterion  = FirstTestCriterion::class;
94
        $secondCriterion = SecondTestCriterion::class;
95
96
        $userRepository->pushCriterion([$firstCriterion]);
97
        $userRepository->pushCriterion([$secondCriterion]);
98
99
        $this->assertAttributeCount(2, 'criteria', $userRepository);
100
    }
101
102
    public function testPushTwoDifferentClosureCriteria()
103
    {
104
        $userRepository = $this->userRepository();
105
        $firstCriterion = function ($query, $repository) {
106
            return $query->where('id', 1);
107
        };
108
        $secondCriterion = function ($query, $repository) {
109
            return $query->where('id', 2);
110
        };
111
112
        $userRepository->pushCriterion($firstCriterion);
113
        $userRepository->pushCriterion($secondCriterion);
114
115
        $this->assertAttributeCount(2, 'criteria', $userRepository);
116
    }
117
118
    public function testPushTwoSimilarCriteria()
119
    {
120
        $userRepository = $this->userRepository();
121
        $firstCriterion = FirstTestCriterion::class;
122
123
        $userRepository->pushCriterion($firstCriterion);
124
        $userRepository->pushCriterion($firstCriterion);
125
126
        $this->assertAttributeCount(1, 'criteria', $userRepository);
127
    }
128
129
    public function testPushCriteria()
130
    {
131
        $userRepository = $this->userRepository();
132
133
        $firstCriterion  = FirstTestCriterion::class;
134
        $secondCriterion = new SecondTestCriterion();
135
        $thirdCriterion  = function ($query, $repository) {
136
            return $query->where('id', 1);
137
        };
138
139
        $userRepository->pushCriteria([
140
            $firstCriterion,
141
            $secondCriterion,
142
            $thirdCriterion,
143
        ]);
144
145
        $this->assertAttributeCount(3, 'criteria', $userRepository);
146
    }
147
148
    public function testRemoveCriterionWhenPushedByClassName()
149
    {
150
        $userRepository  = $this->userRepository();
151
        $firstCriterion  = FirstTestCriterion::class;
152
        $secondCriterion = SecondTestCriterion::class;
153
154
        $userRepository->pushCriterion($firstCriterion);
155
        $this->assertAttributeCount(1, 'criteria', $userRepository);
156
157
        $userRepository->removeCriterion($firstCriterion);
158
        $this->assertAttributeCount(0, 'criteria', $userRepository);
159
160
        $userRepository->pushCriterion($firstCriterion);
161
        $userRepository->pushCriterion($secondCriterion);
162
        $this->assertAttributeCount(2, 'criteria', $userRepository);
163
164
        $userRepository->removeCriterion($firstCriterion);
165
        $this->assertAttributeCount(1, 'criteria', $userRepository);
166
        $userRepository->removeCriterion($firstCriterion);
167
        $this->assertAttributeCount(1, 'criteria', $userRepository);
168
        $userRepository->removeCriterion($secondCriterion);
169
        $this->assertAttributeCount(0, 'criteria', $userRepository);
170
    }
171
172
    public function testRemoveCriterionWhenPushedObject()
173
    {
174
        $userRepository  = $this->userRepository();
175
        $firstCriterion  = new FirstTestCriterion();
176
        $secondCriterion = new SecondTestCriterion();
177
178
        $userRepository->pushCriterion($firstCriterion);
179
        $this->assertAttributeCount(1, 'criteria', $userRepository);
180
181
        $userRepository->removeCriterion($firstCriterion);
182
        $this->assertAttributeCount(0, 'criteria', $userRepository);
183
184
        $userRepository->pushCriterion($firstCriterion);
185
        $userRepository->pushCriterion($secondCriterion);
186
        $this->assertAttributeCount(2, 'criteria', $userRepository);
187
188
        $userRepository->removeCriterion($firstCriterion);
189
        $this->assertAttributeCount(1, 'criteria', $userRepository);
190
        $userRepository->removeCriterion($firstCriterion);
191
        $this->assertAttributeCount(1, 'criteria', $userRepository);
192
        $userRepository->removeCriterion($secondCriterion);
193
        $this->assertAttributeCount(0, 'criteria', $userRepository);
194
195
        $userRepository->pushCriterion($firstCriterion);
196
        $userRepository->removeCriterion(FirstTestCriterion::class);
197
        $this->assertAttributeCount(0, 'criteria', $userRepository);
198
    }
199
200
    public function testRemoveCriterionWhenPushedClosures()
201
    {
202
        $userRepository = $this->userRepository();
203
        $firstCriterion = function ($query, $repository) {
204
            return $query->where('id', 1);
205
        };
206
207
        $secondCriterion = function ($query, $repository) {
208
            return $query->where('id', 2);
209
        };
210
211
        $userRepository->pushCriterion($firstCriterion);
212
        $this->assertAttributeCount(1, 'criteria', $userRepository);
213
214
        $userRepository->removeCriterion($firstCriterion);
215
        $this->assertAttributeCount(0, 'criteria', $userRepository);
216
217
        $userRepository->pushCriterion($firstCriterion);
218
        $userRepository->pushCriterion($secondCriterion);
219
        $this->assertAttributeCount(2, 'criteria', $userRepository);
220
221
        $userRepository->removeCriterion($firstCriterion);
222
        $this->assertAttributeCount(1, 'criteria', $userRepository);
223
        $userRepository->removeCriterion($firstCriterion);
224
        $this->assertAttributeCount(1, 'criteria', $userRepository);
225
        $userRepository->removeCriterion($secondCriterion);
226
        $this->assertAttributeCount(0, 'criteria', $userRepository);
227
    }
228
229
    public function testRemoveCriteria()
230
    {
231
        $userRepository = $this->userRepository();
232
        $firstCriterion = function ($query, $repository) {
233
            return $query->where('id', 1);
234
        };
235
236
        $secondCriterion = function ($query, $repository) {
237
            return $query->where('id', 2);
238
        };
239
240
        $userRepository->pushCriterion($firstCriterion);
241
        $userRepository->pushCriterion($secondCriterion);
242
        $this->assertAttributeCount(2, 'criteria', $userRepository);
243
244
        $userRepository->removeCriteria([$firstCriterion, $secondCriterion]);
245
        $this->assertAttributeCount(0, 'criteria', $userRepository);
246
247
        $userRepository->pushCriterion($firstCriterion);
248
        $userRepository->pushCriterion($secondCriterion);
249
        $userRepository->removeCriteria([$firstCriterion]);
250
        $userRepository->removeCriteria([$secondCriterion]);
251
        $this->assertAttributeCount(0, 'criteria', $userRepository);
252
    }
253
254
    public function testFlushCriteria()
255
    {
256
        $userRepository = $this->userRepository();
257
258
        $userRepository->pushCriteria([
259
            new FirstTestCriterion(),
260
            new SecondTestCriterion(),
261
        ]);
262
263
        $this->assertAttributeCount(2, 'criteria', $userRepository);
264
        $userRepository->flushCriteria();
265
        $this->assertAttributeCount(0, 'criteria', $userRepository);
266
    }
267
268
    public function testSetDefaultCriteria()
269
    {
270
        $userRepository = $this->userRepository();
271
272
        $userRepository->setDefaultCriteria([
273
            new FirstTestCriterion(),
274
            new SecondTestCriterion(),
275
        ]);
276
277
        $this->assertAttributeCount(2, 'defaultCriteria', $userRepository);
278
    }
279
280
    public function testGetDefaultCriteria()
281
    {
282
        $userRepository = $this->userRepository();
283
        $criteria       = [
284
            new FirstTestCriterion(),
285
            new SecondTestCriterion(),
286
        ];
287
288
        $userRepository->setDefaultCriteria($criteria);
289
        $defaultCriteria = $userRepository->getDefaultCriteria();
290
291
        $this->assertArrayHasKey(FirstTestCriterion::class, $defaultCriteria);
292
        $this->assertArrayHasKey(SecondTestCriterion::class, $defaultCriteria);
293
    }
294
295
    public function testGetCriteria()
296
    {
297
        $userRepository = $this->userRepository();
298
        $criteria       = [
299
            new FirstTestCriterion(),
300
            new SecondTestCriterion(),
301
        ];
302
303
        $userRepository->pushCriteria($criteria);
304
305
        $this->assertArrayHasKey(FirstTestCriterion::class, $userRepository->getCriteria());
306
        $this->assertArrayHasKey(SecondTestCriterion::class, $userRepository->getCriteria());
307
    }
308
309
    public function testGetCriteriaWithDefault()
310
    {
311
        $userRepository = $this->userRepository();
312
313
        $criteria = [
314
            new FirstTestCriterion(),
315
            new SecondTestCriterion(),
316
        ];
317
318
        $defaultCriteria = [
319
            function ($query, $repository) {
320
                return $query->where('id', 1);
321
            },
322
        ];
323
324
        $userRepository->setDefaultCriteria($defaultCriteria)->pushCriteria($criteria);
325
326
        $this->assertCount(3, $userRepository->getCriteria());
327
    }
328
329
    public function testGetCriteriaWithSkipCriteria()
330
    {
331
        $userRepository = $this->userRepository();
332
333
        $criteria = [
334
            new FirstTestCriterion(),
335
            new SecondTestCriterion(),
336
        ];
337
338
        $userRepository->pushCriteria($criteria)->skipCriteria();
339
340
        $this->assertAttributeEquals(true, 'skipCriteria', $userRepository);
341
        $this->assertEmpty($userRepository->getCriteria());
342
    }
343
344
    public function testGetCriteriaWithDefaultWithSkipCriteria()
345
    {
346
        $userRepository = $this->userRepository();
347
348
        $criteria = [
349
            new FirstTestCriterion(),
350
            new SecondTestCriterion(),
351
        ];
352
        $defaultCriteria = [
353
            function ($query, $repository) {
354
                return $query->where('id', 1);
355
            },
356
        ];
357
358
        $userRepository->setDefaultCriteria($defaultCriteria)->pushCriteria($criteria)->skipCriteria();
359
360
        $this->assertAttributeEquals(true, 'skipCriteria', $userRepository);
361
        $this->assertEmpty($userRepository->getCriteria());
362
    }
363
364
    public function testGetCriteriaWithSkipDefaultCriteria()
365
    {
366
        $userRepository = $this->userRepository();
367
368
        $criteria = [
369
            new FirstTestCriterion(),
370
            new SecondTestCriterion(),
371
        ];
372
        $defaultCriteria = [
373
            function ($query, $repository) {
374
                return $query->where('id', 1);
375
            },
376
        ];
377
378
        $userRepository->setDefaultCriteria($defaultCriteria)->pushCriteria($criteria)->skipDefaultCriteria();
379
        $this->assertAttributeEquals(true, 'skipDefaultCriteria', $userRepository);
380
        $this->assertCount(2, $userRepository->getCriteria());
381
    }
382
383
    public function testHasCriterion()
384
    {
385
        $userRepository = $this->userRepository();
386
387
        $criteria = [
388
            new FirstTestCriterion(),
389
            new SecondTestCriterion(),
390
        ];
391
392
        $userRepository->pushCriteria($criteria);
393
394
        $this->assertTrue($userRepository->hasCriterion(FirstTestCriterion::class));
395
        $this->assertTrue($userRepository->hasCriterion(SecondTestCriterion::class));
396
    }
397
398
    public function testHasCriterionByClosure()
399
    {
400
        $userRepository = $this->userRepository();
401
        $firstCriteria  = function ($query, $repository) {
402
            return $query->where('id', 1);
403
        };
404
405
        $secondCriteria = function ($query, $repository) {
406
            return $query->where('id', 2);
407
        };
408
409
        $userRepository->pushCriteria([$firstCriteria, $secondCriteria]);
410
411
        $this->assertTrue($userRepository->hasCriterion($firstCriteria));
412
        $this->assertTrue($userRepository->hasCriterion($secondCriteria));
413
    }
414
415
    public function testGetCriterion()
416
    {
417
        $userRepository = $this->userRepository();
418
        $userRepository->pushCriteria([
419
            FirstTestCriterion::class,
420
            SecondTestCriterion::class,
421
        ]);
422
423
        $this->assertInstanceOf(FirstTestCriterion::class, $userRepository->getCriterion(FirstTestCriterion::class));
424
        $this->assertInstanceOf(SecondTestCriterion::class, $userRepository->getCriterion(SecondTestCriterion::class));
425
    }
426
427
    public function testGetCriterionByClosure()
428
    {
429
        $userRepository = $this->userRepository();
430
        $firstCriteria  = function ($query, $repository) {
431
            return $query->where('id', 1);
432
        };
433
434
        $secondCriteria = function ($query, $repository) {
435
            return $query->where('id', 2);
436
        };
437
438
        $userRepository->pushCriteria([$firstCriteria, $secondCriteria]);
439
        $this->assertSame($firstCriteria, $userRepository->getCriterion($firstCriteria));
440
        $this->assertSame($secondCriteria, $userRepository->getCriterion($secondCriteria));
441
        $this->assertNotSame($secondCriteria, $userRepository->getCriterion($firstCriteria));
442
    }
443
444
    public function testApplyCriteria()
445
    {
446
        $userRepository = $this->userRepository();
447
        $userRepository->pushCriteria([
448
            new FirstTestCriterion(),
449
            new SecondTestCriterion(),
450
        ]);
451
452
        $resultQuery = $userRepository->applyCriteria($userRepository->createModel(), $userRepository);
453
454
        $this->assertEquals('select * from "users" where "id" = ? and "id" = ?', $resultQuery->toSql());
455
        $this->assertEquals([0 => 1, 1 => 2], $resultQuery->getBindings());
456
    }
457
458
    public function testApplyCriteriaWithClosureCriteria()
459
    {
460
        $userRepository = $this->userRepository();
461
        $userRepository->pushCriteria([
462
            new FirstTestCriterion(),
463
            new SecondTestCriterion(),
464
        ])->pushCriterion(function ($query, $repository) {
465
            return $query->where('id', 3);
466
        });
467
468
        $resultQuery = $userRepository->applyCriteria($userRepository->createModel(), $userRepository);
469
470
        $this->assertEquals('select * from "users" where "id" = ? and "id" = ? and "id" = ?', $resultQuery->toSql());
471
        $this->assertEquals([0 => 1, 1 => 2, 2 => 3], $resultQuery->getBindings());
472
    }
473
}
474
475
class FirstTestCriterion implements \Rinvex\Repository\Contracts\CriterionContract
476
{
477
    public function apply($query, $repository)
478
    {
479
        return $query->where('id', 1);
480
    }
481
}
482
483
class SecondTestCriterion implements \Rinvex\Repository\Contracts\CriterionContract
484
{
485
    public function apply($query, $repository)
486
    {
487
        return $query->where('id', 2);
488
    }
489
}
490
491
class ThirdTestWithArgumentsCriterion implements \Rinvex\Repository\Contracts\CriterionContract
492
{
493
    protected $from;
494
    protected $to;
495
496
    public function __construct($from, $to)
497
    {
498
        $this->from = $from;
499
        $this->to   = $to;
500
    }
501
502
    public function apply($query, $repository)
503
    {
504
        return $query->whereBetween('created_at', [$this->from, $this->to]);
505
    }
506
}
507