AbstractRepositoryTest   A
last analyzed

Complexity

Total Complexity 5

Size/Duplication

Total Lines 936
Duplicated Lines 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 495
c 2
b 0
f 0
dl 0
loc 936
rs 10
wmc 5

40 Methods

Rating   Name   Duplication   Size   Complexity  
A testUpdateToString() 0 23 1
A testFindOne() 0 29 1
A testFindOneToString() 0 14 1
A testUpdateWithException() 0 31 1
A testUpdateWithoutEntity() 0 19 1
A testCountWithException() 0 19 1
A hp$0 ➔ __construct() 0 10 1
A testUpdate() 0 33 1
B hp$0 ➔ createEntity() 0 68 1
A hp$0 ➔ setDataOriginal() 0 5 1
A testFind() 0 36 2
A testCreateQueryBuilder() 0 16 1
A testUpdateWithoutEntityChanges() 0 20 1
A testFindWithException() 0 21 1
A testFindOneWithException() 0 21 1
A testCount() 0 15 1
A testAddPaginateQuery() 0 24 1
A testDelete() 0 24 1
A testUpdateIgnoreToString() 0 23 1
A testDeleteWithException() 0 29 1
A testDeleteToString() 0 21 1
A testDeleteWithEntityWithoutPrimaryKeys() 0 11 1
A testUpdateIgnore() 0 32 1
A hp$0 ➔ setIsNew() 0 5 1
A testCountToString() 0 13 1
A testFindToString() 0 14 1
A testGetPaginateResult() 0 34 2
A testDeleteWithoutEntity() 0 18 1
A testCountWithWrongCommand() 0 14 1
A hp$0 ➔ setIsSaved() 0 5 1
A testInsertWithSqlException() 0 21 1
A testReplace() 0 19 1
A setUp() 0 41 1
A testReplaceToString() 0 14 1
createEntity() 0 68 ?
A testInsertToString() 0 14 1
A testInsertWithoutEntity() 0 12 1
A testInsertIgnoreToString() 0 14 1
A testInsert() 0 19 1
A testInsertIgnore() 0 19 1
1
<?php declare(strict_types=1);
2
3
namespace Janisbiz\LightOrm\Tests\Unit\Dms\MySQL\Repository;
4
5
use Janisbiz\LightOrm\Connection\ConnectionInterface;
6
use Janisbiz\LightOrm\Dms\MySQL\Enum\CommandEnum;
7
use Janisbiz\LightOrm\Dms\MySQL\Repository\AbstractRepository;
8
use Janisbiz\LightOrm\Dms\MySQL\Repository\RepositoryException;
9
use Janisbiz\LightOrm\Entity\BaseEntity;
10
use Janisbiz\LightOrm\Entity\EntityInterface;
11
use Janisbiz\LightOrm\Generator\Writer\WriterInterface;
12
use Janisbiz\LightOrm\QueryBuilder\QueryBuilderInterface;
13
use Janisbiz\LightOrm\Tests\Unit\Dms\MySQL\Generator\Dms\DmsTableTest;
14
use Janisbiz\LightOrm\Tests\Unit\Dms\MySQL\QueryBuilder\QueryBuilderTrait;
15
use Janisbiz\LightOrm\Tests\Unit\ReflectionTrait;
16
use PHPUnit\Framework\TestCase;
17
18
class AbstractRepositoryTest extends TestCase
19
{
20
    use QueryBuilderTrait;
21
    use ReflectionTrait;
22
23
    const COLUMN_AUTO_INCREMENT = 'col_a_i';
24
    const COLUMN_AUTO_INCREMENT_VALUE = 1;
25
    const COLUMN_ONE = 'col_1';
26
    const COLUMN_ONE_UPDATE_VALUE = 'val1Update';
27
28
    const TABLE = 'table';
29
30
    const RESULT_COUNT = 3;
31
32
    const PAGINATE_CURRENT_PAGE = 2;
33
    const PAGINATE_PAGE_SIZE = 10;
34
35
    /**
36
     * @var \PDOStatement|\PHPUnit_Framework_MockObject_MockObject
37
     */
38
    private $statement;
39
40
    /**
41
     * @var ConnectionInterface|\PHPUnit_Framework_MockObject_MockObject
42
     */
43
    private $connection;
44
45
    /**
46
     * @var EntityInterface
47
     */
48
    private $entity;
49
50
    /**
51
     * @var \ArrayObject|array
52
     */
53
    private $dataOriginal = [
54
        self::COLUMN_AUTO_INCREMENT => null,
55
        self::COLUMN_ONE => 'val1',
56
        'col_2' => 2,
57
        'col_3' => 3.3,
58
    ];
59
60
    /**
61
     * @var \ArrayObject
62
     */
63
    private $data;
64
65
    /**
66
     * @var AbstractRepository|\PHPUnit_Framework_MockObject_MockObject
67
     */
68
    private $abstractRepository;
69
70
    public function setUp()
71
    {
72
        $this->statement = $this->createMock(\PDOStatement::class);
73
74
        $this->connection = $this->createPartialMock(
75
            ConnectionInterface::class,
76
            [
77
                'beginTransaction',
78
                'commit',
79
                'inTransaction',
80
                'lastInsertId',
81
                'prepare',
82
                'rollBack',
83
                'setSqlSafeUpdates',
84
                'unsetSqlSafeUpdates',
85
            ]
86
        );
87
        $this->connection->method('prepare')->willReturn($this->statement);
0 ignored issues
show
Bug introduced by
The method method() does not exist on PHPUnit\Framework\MockObject\MockObject. ( Ignorable by Annotation )

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

87
        $this->connection->/** @scrutinizer ignore-call */ 
88
                           method('prepare')->willReturn($this->statement);

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...
88
89
        $this->entity = $this->createEntity();
90
91
        $this->abstractRepository = $this->getMockForAbstractClass(
92
            AbstractRepository::class,
93
            [],
94
            '',
95
            true,
96
            true,
97
            true,
98
            [
99
                'beginTransaction',
100
                'commit',
101
                'getConnection',
102
                'getEntityClassConstant',
103
                'prepareAndExecute',
104
                'rollBack',
105
            ]
106
        );
107
        $this->abstractRepository
108
            ->expects($this->any())
109
            ->method('getConnection')
110
            ->willReturn($this->connection)
111
        ;
112
    }
113
114
    public function testInsert()
115
    {
116
        $queryBuilder = $this
117
            ->createQueryBuilder($this->abstractRepository, $this->entity)
118
            ->command(CommandEnum::INSERT_INTO)
119
        ;
120
121
        $this->abstractRepository->expects($this->once())->method('commit');
122
        $this->abstractRepository->expects($this->once())->method('prepareAndExecute');
123
124
        $this->connection->method('lastInsertId')->willReturn(static::COLUMN_AUTO_INCREMENT_VALUE);
0 ignored issues
show
Bug introduced by
The method method() does not exist on Janisbiz\LightOrm\Connection\ConnectionInterface. ( Ignorable by Annotation )

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

124
        $this->connection->/** @scrutinizer ignore-call */ 
125
                           method('lastInsertId')->willReturn(static::COLUMN_AUTO_INCREMENT_VALUE);

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...
125
126
        $entity = $this
127
            ->createAccessibleMethod($this->abstractRepository, 'insert')
128
            ->invoke($this->abstractRepository, $queryBuilder)
129
        ;
130
131
        static::assertTrue($entity instanceof $this->entity);
132
        static::assertEquals(static::COLUMN_AUTO_INCREMENT_VALUE, $entity->data()[static::COLUMN_AUTO_INCREMENT]);
133
    }
134
135
    public function testInsertWithSqlException()
136
    {
137
        $queryBuilder = $this
138
            ->createQueryBuilder($this->abstractRepository, $this->entity)
139
            ->command(CommandEnum::INSERT_INTO)
140
        ;
141
142
        $this->abstractRepository->expects($this->once())->method('beginTransaction');
143
        $this->abstractRepository
144
            ->expects($this->once())
145
            ->method('prepareAndExecute')
146
            ->willThrowException(new \Exception('PDO Exception'))
147
        ;
148
        $this->abstractRepository->expects($this->once())->method('rollBack');
149
150
        $this->expectException(\Exception::class);
151
        $this->expectExceptionMessage('PDO Exception');
152
153
        $this
154
            ->createAccessibleMethod($this->abstractRepository, 'insert')
155
            ->invoke($this->abstractRepository, $queryBuilder)
156
        ;
157
    }
158
159
    public function testInsertToString()
160
    {
161
        $queryBuilder = $this
162
            ->createQueryBuilder($this->abstractRepository, $this->entity)
163
            ->command(CommandEnum::INSERT_INTO)
164
        ;
165
166
        $insertQuery = $this
167
            ->createAccessibleMethod($this->abstractRepository, 'insert')
168
            ->invoke($this->abstractRepository, $queryBuilder, true)
169
        ;
170
171
        $this->assertTrue(\is_string($insertQuery));
172
        $this->assertStringStartsWith(CommandEnum::INSERT_INTO, $insertQuery);
173
    }
174
175
    public function testInsertWithoutEntity()
176
    {
177
        $this->expectException(RepositoryException::class);
178
        $this->expectExceptionMessage(
179
            'Cannot perform insert on query without entity! Please create query builder with entity.'
180
        );
181
182
        $queryBuilder = $this->createQueryBuilder($this->abstractRepository);
183
184
        $this
185
            ->createAccessibleMethod($this->abstractRepository, 'insert')
186
            ->invoke($this->abstractRepository, $queryBuilder)
187
        ;
188
    }
189
190
    public function testInsertIgnore()
191
    {
192
        $queryBuilder = $this
193
            ->createQueryBuilder($this->abstractRepository, $this->entity)
194
            ->command(CommandEnum::INSERT_IGNORE_INTO)
195
        ;
196
197
        $this->abstractRepository->expects($this->once())->method('commit');
198
        $this->abstractRepository->expects($this->once())->method('prepareAndExecute');
199
200
        $this->connection->method('lastInsertId')->willReturn(static::COLUMN_AUTO_INCREMENT_VALUE);
201
202
        $entity = $this
203
            ->createAccessibleMethod($this->abstractRepository, 'insertIgnore')
204
            ->invoke($this->abstractRepository, $queryBuilder)
205
        ;
206
207
        static::assertTrue($entity instanceof $this->entity);
208
        static::assertEquals(static::COLUMN_AUTO_INCREMENT_VALUE, $entity->data()[static::COLUMN_AUTO_INCREMENT]);
209
    }
210
211
    public function testInsertIgnoreToString()
212
    {
213
        $queryBuilder = $this
214
            ->createQueryBuilder($this->abstractRepository, $this->entity)
215
            ->command(CommandEnum::INSERT_IGNORE_INTO)
216
        ;
217
218
        $insertIgnoreQuery = $this
219
            ->createAccessibleMethod($this->abstractRepository, 'insertIgnore')
220
            ->invoke($this->abstractRepository, $queryBuilder, true)
221
        ;
222
223
        $this->assertTrue(\is_string($insertIgnoreQuery));
224
        $this->assertStringStartsWith(CommandEnum::INSERT_IGNORE_INTO, $insertIgnoreQuery);
225
    }
226
227
    public function testReplace()
228
    {
229
        $queryBuilder = $this
230
            ->createQueryBuilder($this->abstractRepository, $this->entity)
231
            ->command(CommandEnum::REPLACE_INTO)
232
        ;
233
234
        $this->abstractRepository->expects($this->once())->method('commit');
235
        $this->abstractRepository->expects($this->once())->method('prepareAndExecute');
236
237
        $this->connection->method('lastInsertId')->willReturn(static::COLUMN_AUTO_INCREMENT_VALUE);
238
239
        $entity = $this
240
            ->createAccessibleMethod($this->abstractRepository, 'replace')
241
            ->invoke($this->abstractRepository, $queryBuilder)
242
        ;
243
244
        static::assertTrue($entity instanceof $this->entity);
245
        static::assertEquals(static::COLUMN_AUTO_INCREMENT_VALUE, $entity->data()[static::COLUMN_AUTO_INCREMENT]);
246
    }
247
248
    public function testReplaceToString()
249
    {
250
        $queryBuilder = $this
251
            ->createQueryBuilder($this->abstractRepository, $this->entity)
252
            ->command(CommandEnum::REPLACE_INTO)
253
        ;
254
255
        $replaceQuery = $this
256
            ->createAccessibleMethod($this->abstractRepository, 'replace')
257
            ->invoke($this->abstractRepository, $queryBuilder, true)
258
        ;
259
260
        $this->assertTrue(\is_string($replaceQuery));
261
        $this->assertStringStartsWith(CommandEnum::REPLACE_INTO, $replaceQuery);
262
    }
263
264
    public function testFindOne()
265
    {
266
        $queryBuilder = $this
267
            ->createQueryBuilder($this->abstractRepository, $this->entity)
268
            ->command(CommandEnum::SELECT)
269
        ;
270
271
        $this->statement->expects($this->once())->method('fetch')->willReturn($this->entity);
272
        $this
273
            ->statement
274
            ->expects($this->once())
275
            ->method('setFetchMode')
276
            ->with(
277
                \PDO::FETCH_CLASS,
278
                \get_class($this->entity),
279
                [
280
                    false,
281
                ]
282
            )
283
        ;
284
285
        $this->abstractRepository->expects($this->once())->method('prepareAndExecute')->willReturn($this->statement);
286
287
        $entity = $this
288
            ->createAccessibleMethod($this->abstractRepository, 'findOne')
289
            ->invoke($this->abstractRepository, $queryBuilder)
290
        ;
291
292
        $this->assertTrue($entity instanceof $this->entity);
293
    }
294
295
    public function testFindOneToString()
296
    {
297
        $queryBuilder = $this
298
            ->createQueryBuilder($this->abstractRepository, $this->entity)
299
            ->command(CommandEnum::SELECT)
300
        ;
301
302
        $findOneQuery = $this
303
            ->createAccessibleMethod($this->abstractRepository, 'findOne')
304
            ->invoke($this->abstractRepository, $queryBuilder, true)
305
        ;
306
307
        $this->assertTrue(\is_string($findOneQuery));
308
        $this->assertStringStartsWith(CommandEnum::SELECT, $findOneQuery);
309
    }
310
311
    public function testFindOneWithException()
312
    {
313
        $queryBuilder = $this
314
            ->createQueryBuilder($this->abstractRepository, $this->entity)
315
            ->command(CommandEnum::SELECT)
316
        ;
317
318
        $this->abstractRepository
319
            ->expects($this->once())
320
            ->method('prepareAndExecute')
321
            ->willThrowException(new \Exception('PDO Exception'))
322
        ;
323
324
        $this->abstractRepository->expects($this->once())->method('rollBack');
325
326
        $this->expectException(\Exception::class);
327
        $this->expectExceptionMessage('PDO Exception');
328
329
        $this
330
            ->createAccessibleMethod($this->abstractRepository, 'findOne')
331
            ->invoke($this->abstractRepository, $queryBuilder)
332
        ;
333
    }
334
335
    public function testFind()
336
    {
337
        $queryBuilder = $this
338
            ->createQueryBuilder($this->abstractRepository, $this->entity)
339
            ->command(CommandEnum::SELECT)
340
        ;
341
342
        $entityArray = [
343
            $this->entity,
344
            $this->entity,
345
            $this->entity,
346
        ];
347
        $this->statement->expects($this->once())->method('fetchAll')->willReturn($entityArray);
348
        $this
349
            ->statement
350
            ->expects($this->once())
351
            ->method('setFetchMode')
352
            ->with(
353
                \PDO::FETCH_CLASS,
354
                \get_class($this->entity),
355
                [
356
                    false,
357
                ]
358
            )
359
        ;
360
361
        $this->abstractRepository->expects($this->once())->method('prepareAndExecute')->willReturn($this->statement);
362
363
        $resultArray = $this
364
            ->createAccessibleMethod($this->abstractRepository, 'find')
365
            ->invoke($this->abstractRepository, $queryBuilder)
366
        ;
367
368
        $this->assertCount(\count($entityArray), $resultArray);
369
        foreach ($resultArray as $resultEntity) {
370
            $this->assertTrue($resultEntity instanceof $this->entity);
371
        }
372
    }
373
374
    public function testFindToString()
375
    {
376
        $queryBuilder = $this
377
            ->createQueryBuilder($this->abstractRepository, $this->entity)
378
            ->command(CommandEnum::SELECT)
379
        ;
380
381
        $findQuery = $this
382
            ->createAccessibleMethod($this->abstractRepository, 'find')
383
            ->invoke($this->abstractRepository, $queryBuilder, true)
384
        ;
385
386
        $this->assertTrue(\is_string($findQuery));
387
        $this->assertStringStartsWith(CommandEnum::SELECT, $findQuery);
388
    }
389
390
    public function testFindWithException()
391
    {
392
        $queryBuilder = $this
393
            ->createQueryBuilder($this->abstractRepository, $this->entity)
394
            ->command(CommandEnum::SELECT)
395
        ;
396
397
        $this->abstractRepository
398
            ->expects($this->once())
399
            ->method('prepareAndExecute')
400
            ->willThrowException(new \Exception('PDO Exception'))
401
        ;
402
403
        $this->abstractRepository->expects($this->once())->method('rollBack');
404
405
        $this->expectException(\Exception::class);
406
        $this->expectExceptionMessage('PDO Exception');
407
408
        $this
409
            ->createAccessibleMethod($this->abstractRepository, 'find')
410
            ->invoke($this->abstractRepository, $queryBuilder)
411
        ;
412
    }
413
414
    public function testUpdate()
415
    {
416
        $this
417
            ->entity
418
            ->setIsNew(false)
0 ignored issues
show
Bug introduced by
The method setIsNew() does not exist on Janisbiz\LightOrm\Entity\EntityInterface. Since it exists in all sub-types, consider adding an abstract or default implementation to Janisbiz\LightOrm\Entity\EntityInterface. ( Ignorable by Annotation )

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

418
            ->/** @scrutinizer ignore-call */ 
419
              setIsNew(false)
Loading history...
419
            ->setIsSaved(true)
420
            ->setColAI(static::COLUMN_AUTO_INCREMENT_VALUE)
421
            ->setCol1(static::COLUMN_ONE_UPDATE_VALUE)
422
            ->setDataOriginal(static::COLUMN_AUTO_INCREMENT, static::COLUMN_AUTO_INCREMENT_VALUE)
423
        ;
424
425
        $queryBuilder = $this
426
            ->createQueryBuilder($this->abstractRepository, $this->entity)
427
            ->command(CommandEnum::UPDATE)
428
        ;
429
430
        $this->connection->expects($this->once())->method('setSqlSafeUpdates');
431
        $this->connection->expects($this->once())->method('unsetSqlSafeUpdates');
432
433
        $this->abstractRepository->expects($this->once())->method('prepareAndExecute');
434
        $this->abstractRepository->expects($this->once())->method('commit')->willReturn(true);
435
436
        $entity = $this
437
            ->createAccessibleMethod($this->abstractRepository, 'update')
438
            ->invoke($this->abstractRepository, $queryBuilder)
439
        ;
440
441
        $this->assertTrue($entity instanceof $this->entity);
442
443
        $this->assertEquals($entity->data(static::COLUMN_AUTO_INCREMENT), static::COLUMN_AUTO_INCREMENT_VALUE);
444
        $this->assertEquals(
445
            $entity->dataOriginal()[static::COLUMN_AUTO_INCREMENT],
446
            static::COLUMN_AUTO_INCREMENT_VALUE
447
        );
448
    }
449
450
    public function testUpdateWithoutEntity()
451
    {
452
        $queryBuilder = $this
453
            ->createQueryBuilder($this->abstractRepository)
454
            ->command(CommandEnum::UPDATE)
455
            ->set(static::COLUMN_ONE, static::COLUMN_ONE_UPDATE_VALUE)
456
            ->where(\sprintf('%s = %d', static::COLUMN_AUTO_INCREMENT, static::COLUMN_AUTO_INCREMENT_VALUE))
457
        ;
458
459
        $this->connection->expects($this->once())->method('setSqlSafeUpdates');
460
        $this->connection->expects($this->once())->method('unsetSqlSafeUpdates');
461
462
        $this->abstractRepository->expects($this->once())->method('prepareAndExecute');
463
        $this->abstractRepository->expects($this->once())->method('commit')->willReturn(true);
464
465
        $this->assertTrue(
466
            $this
467
                ->createAccessibleMethod($this->abstractRepository, 'update')
468
                ->invoke($this->abstractRepository, $queryBuilder)
469
        );
470
    }
471
472
    public function testUpdateWithoutEntityChanges()
473
    {
474
        $queryBuilder = $this
475
            ->createQueryBuilder($this->abstractRepository, $this->entity)
476
            ->command(CommandEnum::UPDATE)
477
        ;
478
479
        $this->connection->expects($this->never())->method('setSqlSafeUpdates');
480
        $this->connection->expects($this->never())->method('unsetSqlSafeUpdates');
481
482
        $this->abstractRepository->expects($this->never())->method('prepareAndExecute');
483
        $this->abstractRepository->expects($this->never())->method('commit');
484
485
        $entity = $this
486
            ->createAccessibleMethod($this->abstractRepository, 'update')
487
            ->invoke($this->abstractRepository, $queryBuilder)
488
        ;
489
490
        $this->assertTrue($entity instanceof $this->entity);
491
        $this->assertEquals($this->entity, $entity);
492
    }
493
494
    public function testUpdateToString()
495
    {
496
        $this
497
            ->entity
498
            ->setIsNew(false)
499
            ->setIsSaved(true)
500
            ->setColAI(static::COLUMN_AUTO_INCREMENT_VALUE)
501
            ->setCol1(static::COLUMN_ONE_UPDATE_VALUE)
502
            ->setDataOriginal(static::COLUMN_AUTO_INCREMENT, static::COLUMN_AUTO_INCREMENT_VALUE)
503
        ;
504
505
        $queryBuilder = $this
506
            ->createQueryBuilder($this->abstractRepository, $this->entity)
507
            ->command(CommandEnum::UPDATE)
508
        ;
509
510
        $updateQuery = $this
511
            ->createAccessibleMethod($this->abstractRepository, 'update')
512
            ->invoke($this->abstractRepository, $queryBuilder, true)
513
        ;
514
515
        $this->assertTrue(\is_string($updateQuery));
516
        $this->assertStringStartsWith(CommandEnum::UPDATE, $updateQuery);
517
    }
518
519
    public function testUpdateWithException()
520
    {
521
        $this
522
            ->entity
523
            ->setIsNew(false)
524
            ->setIsSaved(true)
525
            ->setColAI(static::COLUMN_AUTO_INCREMENT_VALUE)
526
            ->setCol1(static::COLUMN_ONE_UPDATE_VALUE)
527
            ->setDataOriginal(static::COLUMN_AUTO_INCREMENT, static::COLUMN_AUTO_INCREMENT_VALUE)
528
        ;
529
530
        $queryBuilder = $this
531
            ->createQueryBuilder($this->abstractRepository, $this->entity)
532
            ->command(CommandEnum::UPDATE)
533
        ;
534
535
        $this->connection->expects($this->once())->method('setSqlSafeUpdates');
536
        $this->connection->expects($this->once())->method('unsetSqlSafeUpdates');
537
538
        $this->abstractRepository
539
            ->expects($this->once())
540
            ->method('prepareAndExecute')
541
            ->willThrowException(new \Exception('PDO Exception'))
542
        ;
543
544
        $this->expectException(\Exception::class);
545
        $this->expectExceptionMessage('PDO Exception');
546
547
        $this
548
            ->createAccessibleMethod($this->abstractRepository, 'update')
549
            ->invoke($this->abstractRepository, $queryBuilder)
550
        ;
551
    }
552
553
    public function testUpdateIgnore()
554
    {
555
        $this
556
            ->entity
557
            ->setIsNew(false)
558
            ->setIsSaved(true)
559
            ->setColAI(static::COLUMN_AUTO_INCREMENT_VALUE)
560
            ->setCol1(static::COLUMN_ONE_UPDATE_VALUE)
561
            ->setDataOriginal(static::COLUMN_AUTO_INCREMENT, static::COLUMN_AUTO_INCREMENT_VALUE)
562
        ;
563
564
        $queryBuilder = $this
565
            ->createQueryBuilder($this->abstractRepository, $this->entity)
566
            ->command(CommandEnum::UPDATE_IGNORE)
567
        ;
568
569
        $this->connection->expects($this->once())->method('setSqlSafeUpdates');
570
        $this->connection->expects($this->once())->method('unsetSqlSafeUpdates');
571
572
        $this->abstractRepository->expects($this->once())->method('prepareAndExecute');
573
        $this->abstractRepository->expects($this->once())->method('commit')->willReturn(true);
574
575
        $entity = $this
576
            ->createAccessibleMethod($this->abstractRepository, 'updateIgnore')
577
            ->invoke($this->abstractRepository, $queryBuilder)
578
        ;
579
580
        $this->assertTrue($entity instanceof $this->entity);
581
        $this->assertEquals($entity->data()[static::COLUMN_AUTO_INCREMENT], static::COLUMN_AUTO_INCREMENT_VALUE);
582
        $this->assertEquals(
583
            $entity->dataOriginal()[static::COLUMN_AUTO_INCREMENT],
584
            static::COLUMN_AUTO_INCREMENT_VALUE
585
        );
586
    }
587
588
    public function testUpdateIgnoreToString()
589
    {
590
        $this
591
            ->entity
592
            ->setIsNew(false)
593
            ->setIsSaved(true)
594
            ->setColAI(static::COLUMN_AUTO_INCREMENT_VALUE)
595
            ->setCol1(static::COLUMN_ONE_UPDATE_VALUE)
596
            ->setDataOriginal(static::COLUMN_AUTO_INCREMENT, static::COLUMN_AUTO_INCREMENT_VALUE)
597
        ;
598
599
        $queryBuilder = $this
600
            ->createQueryBuilder($this->abstractRepository, $this->entity)
601
            ->command(CommandEnum::UPDATE_IGNORE)
602
        ;
603
604
        $updateIgnoreQuery = $this
605
            ->createAccessibleMethod($this->abstractRepository, 'updateIgnore')
606
            ->invoke($this->abstractRepository, $queryBuilder, true)
607
        ;
608
609
        $this->assertTrue(\is_string($updateIgnoreQuery));
610
        $this->assertStringStartsWith(CommandEnum::UPDATE_IGNORE, $updateIgnoreQuery);
611
    }
612
613
    public function testDelete()
614
    {
615
        $this
616
            ->entity
617
            ->setIsNew(false)
618
            ->setIsSaved(true)
619
            ->setColAI(static::COLUMN_AUTO_INCREMENT_VALUE)
620
        ;
621
622
        $queryBuilder = $this
623
            ->createQueryBuilder($this->abstractRepository, $this->entity)
624
            ->command(CommandEnum::DELETE)
625
        ;
626
627
        $this->connection->expects($this->once())->method('setSqlSafeUpdates');
628
        $this->connection->expects($this->once())->method('unsetSqlSafeUpdates');
629
630
        $this->abstractRepository->expects($this->once())->method('prepareAndExecute');
631
        $this->abstractRepository->expects($this->once())->method('commit')->willReturn(true);
632
633
        $this->assertTrue(
634
            $this
635
                ->createAccessibleMethod($this->abstractRepository, 'delete')
636
                ->invoke($this->abstractRepository, $queryBuilder)
637
        );
638
    }
639
640
    public function testDeleteWithoutEntity()
641
    {
642
        $queryBuilder = $this
643
            ->createQueryBuilder($this->abstractRepository)
644
            ->command(CommandEnum::DELETE)
645
            ->where(\sprintf('%s = %d', static::COLUMN_AUTO_INCREMENT, static::COLUMN_AUTO_INCREMENT_VALUE))
646
        ;
647
648
        $this->connection->expects($this->once())->method('setSqlSafeUpdates');
649
        $this->connection->expects($this->once())->method('unsetSqlSafeUpdates');
650
651
        $this->abstractRepository->expects($this->once())->method('prepareAndExecute');
652
        $this->abstractRepository->expects($this->once())->method('commit')->willReturn(true);
653
654
        $this->assertTrue(
655
            $this
656
                ->createAccessibleMethod($this->abstractRepository, 'delete')
657
                ->invoke($this->abstractRepository, $queryBuilder)
658
        );
659
    }
660
661
    public function testDeleteWithEntityWithoutPrimaryKeys()
662
    {
663
        $queryBuilder = $this
664
            ->createQueryBuilder($this->abstractRepository, $this->entity)
665
            ->command(CommandEnum::DELETE)
666
        ;
667
668
        $this->assertFalse(
669
            $this
670
                ->createAccessibleMethod($this->abstractRepository, 'delete')
671
                ->invoke($this->abstractRepository, $queryBuilder)
672
        );
673
    }
674
675
    public function testDeleteToString()
676
    {
677
        $this
678
            ->entity
679
            ->setIsNew(false)
680
            ->setIsSaved(true)
681
            ->setColAI(static::COLUMN_AUTO_INCREMENT_VALUE)
682
        ;
683
684
        $queryBuilder = $this
685
            ->createQueryBuilder($this->abstractRepository, $this->entity)
686
            ->command(CommandEnum::DELETE)
687
        ;
688
689
        $deleteQuery = $this
690
            ->createAccessibleMethod($this->abstractRepository, 'delete')
691
            ->invoke($this->abstractRepository, $queryBuilder, true)
692
        ;
693
694
        $this->assertTrue(\is_string($deleteQuery));
695
        $this->assertStringStartsWith(CommandEnum::DELETE, $deleteQuery);
696
    }
697
698
    public function testDeleteWithException()
699
    {
700
        $this
701
            ->entity
702
            ->setIsNew(false)
703
            ->setIsSaved(true)
704
            ->setColAI(static::COLUMN_AUTO_INCREMENT_VALUE)
705
        ;
706
707
        $queryBuilder = $this
708
            ->createQueryBuilder($this->abstractRepository, $this->entity)
709
            ->command(CommandEnum::DELETE)
710
        ;
711
712
        $this->connection->expects($this->once())->method('setSqlSafeUpdates');
713
        $this->connection->expects($this->once())->method('unsetSqlSafeUpdates');
714
715
        $this->abstractRepository
716
            ->expects($this->once())
717
            ->method('prepareAndExecute')
718
            ->willThrowException(new \Exception('PDO Exception'))
719
        ;
720
721
        $this->expectException(\Exception::class);
722
        $this->expectExceptionMessage('PDO Exception');
723
724
        $this
725
            ->createAccessibleMethod($this->abstractRepository, 'delete')
726
            ->invoke($this->abstractRepository, $queryBuilder)
727
        ;
728
    }
729
730
    public function testCount()
731
    {
732
        $queryBuilder = $this->createQueryBuilder($this->abstractRepository)->command(CommandEnum::SELECT);
733
734
        $this->statement->expects($this->once())->method('fetchColumn')->with(0)->willReturn(static::RESULT_COUNT);
735
736
        $this->abstractRepository->expects($this->once())->method('prepareAndExecute')->willReturn($this->statement);
737
        $this->abstractRepository->method('getEntityClassConstant')->willReturn(static::TABLE);
0 ignored issues
show
Bug introduced by
The method method() does not exist on Janisbiz\LightOrm\Dms\My...tory\AbstractRepository. ( Ignorable by Annotation )

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

737
        $this->abstractRepository->/** @scrutinizer ignore-call */ 
738
                                   method('getEntityClassConstant')->willReturn(static::TABLE);

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...
738
739
        $resultCount = $this
740
            ->createAccessibleMethod($this->abstractRepository, 'count')
741
            ->invoke($this->abstractRepository, $queryBuilder)
742
        ;
743
744
        $this->assertEquals(static::RESULT_COUNT, $resultCount);
745
    }
746
747
    public function testCountWithWrongCommand()
748
    {
749
        $queryBuilder = $this->createQueryBuilder($this->abstractRepository)->command(CommandEnum::DELETE);
750
751
        $this->abstractRepository->method('getEntityClassConstant')->willReturn(static::TABLE);
752
753
        $this->expectException(RepositoryException::class);
754
        $this->expectExceptionMessage(
755
            'Command "DELETE" is not a valid command for count query! Use "SELECT" command to execute count query.'
756
        );
757
758
        $this
759
            ->createAccessibleMethod($this->abstractRepository, 'count')
760
            ->invoke($this->abstractRepository, $queryBuilder)
761
        ;
762
    }
763
764
    public function testCountToString()
765
    {
766
        $queryBuilder = $this->createQueryBuilder($this->abstractRepository)->command(CommandEnum::SELECT);
767
768
        $this->abstractRepository->method('getEntityClassConstant')->willReturn(static::TABLE);
769
770
        $countQuery = $this
771
            ->createAccessibleMethod($this->abstractRepository, 'count')
772
            ->invoke($this->abstractRepository, $queryBuilder, true)
773
        ;
774
775
        $this->assertTrue(\is_string($countQuery));
776
        $this->assertStringStartsWith(CommandEnum::SELECT, $countQuery);
777
    }
778
779
    public function testCountWithException()
780
    {
781
        $queryBuilder = $this->createQueryBuilder($this->abstractRepository)->command(CommandEnum::SELECT);
782
783
        $this->abstractRepository->method('getEntityClassConstant')->willReturn(static::TABLE);
784
        $this->abstractRepository
785
            ->expects($this->once())
786
            ->method('prepareAndExecute')
787
            ->willThrowException(new \Exception('PDO Exception'))
788
        ;
789
790
        $this->abstractRepository->expects($this->once())->method('rollBack');
791
792
        $this->expectException(\Exception::class);
793
        $this->expectExceptionMessage('PDO Exception');
794
795
        $this
796
            ->createAccessibleMethod($this->abstractRepository, 'count')
797
            ->invoke($this->abstractRepository, $queryBuilder)
798
        ;
799
    }
800
801
    public function testCreateQueryBuilder()
802
    {
803
        $createQueryBuilderMethod = new \ReflectionMethod($this->abstractRepository, 'createQueryBuilder');
804
        $createQueryBuilderMethod->setAccessible(true);
805
806
807
        $this->abstractRepository
808
            ->expects($this->any())
809
            ->method('getEntityClassConstant')
810
            ->withConsecutive([WriterInterface::CLASS_CONSTANT_TABLE_NAME])
811
            ->willReturn(DmsTableTest::TABLE_NAME)
812
        ;
813
814
        $queryBuilder = $createQueryBuilderMethod->invoke($this->abstractRepository);
815
816
        $this->assertTrue($queryBuilder instanceof QueryBuilderInterface);
817
    }
818
819
    public function testAddPaginateQuery()
820
    {
821
        $queryBuilder = $this
822
            ->createQueryBuilder($this->abstractRepository, $this->entity)
823
            ->command(CommandEnum::SELECT)
824
        ;
825
826
        $this
827
            ->createAccessibleMethod($this->abstractRepository, 'addPaginateQuery')
828
            ->invoke(
829
                $this->abstractRepository,
830
                $queryBuilder,
831
                static::PAGINATE_PAGE_SIZE,
832
                static::PAGINATE_CURRENT_PAGE
833
            )
834
        ;
835
836
        $this->assertEquals(
837
            static::PAGINATE_PAGE_SIZE,
838
            $this->createAccessibleProperty($queryBuilder, 'limit')->getValue($queryBuilder)
839
        );
840
        $this->assertEquals(
841
            static::PAGINATE_PAGE_SIZE * static::PAGINATE_CURRENT_PAGE - static::PAGINATE_PAGE_SIZE,
842
            $this->createAccessibleProperty($queryBuilder, 'offset')->getValue($queryBuilder)
843
        );
844
    }
845
846
    public function testGetPaginateResult()
847
    {
848
        $queryBuilder = $this->createQueryBuilder($this->abstractRepository, $this->entity);
849
850
        $entityArray = [
851
            $this->entity,
852
            $this->entity,
853
            $this->entity,
854
        ];
855
856
        $this->statement->expects($this->once())->method('fetchAll')->willReturn($entityArray);
857
        $this
858
            ->statement
859
            ->expects($this->once())
860
            ->method('setFetchMode')
861
            ->with(
862
                \PDO::FETCH_CLASS,
863
                \get_class($this->entity),
864
                [
865
                    false,
866
                ]
867
            )
868
        ;
869
870
        $this->abstractRepository->expects($this->once())->method('prepareAndExecute')->willReturn($this->statement);
871
872
        $resultArray = $this
873
            ->createAccessibleMethod($this->abstractRepository, 'getPaginateResult')
874
            ->invoke($this->abstractRepository, $queryBuilder)
875
        ;
876
877
        $this->assertCount(\count($entityArray), $resultArray);
878
        foreach ($resultArray as $resultEntity) {
879
            $this->assertTrue($resultEntity instanceof $this->entity);
880
        }
881
    }
882
883
    /**
884
     * @return EntityInterface
885
     */
886
    private function createEntity()
887
    {
888
        return new class(
889
            $this->dataOriginal,
0 ignored issues
show
Bug introduced by
It seems like $this->dataOriginal can also be of type ArrayObject; however, parameter $dataOriginal of anonymous//tests/Unit/Dm...st.php$0::__construct() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

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

889
            /** @scrutinizer ignore-type */ $this->dataOriginal,
Loading history...
890
            \array_keys($this->dataOriginal),
0 ignored issues
show
Bug introduced by
It seems like $this->dataOriginal can also be of type ArrayObject; however, parameter $input of array_keys() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

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

890
            \array_keys(/** @scrutinizer ignore-type */ $this->dataOriginal),
Loading history...
891
            [
892
                AbstractRepositoryTest::COLUMN_AUTO_INCREMENT,
893
            ],
894
            [
895
                AbstractRepositoryTest::COLUMN_AUTO_INCREMENT,
896
            ]
897
        ) extends BaseEntity
898
        {
899
            const TABLE_NAME = AbstractRepositoryTest::TABLE;
900
901
            /**
902
             * @param array $dataOriginal
903
             * @param array $columns
904
             * @param array $primaryKeys
905
             * @param array $primaryKeysAutoIncrement
906
             */
907
            public function __construct(
908
                array &$dataOriginal,
909
                array $columns,
910
                array $primaryKeys,
911
                array $primaryKeysAutoIncrement
912
            ) {
913
                $this->dataOriginal = $this->data = $dataOriginal;
914
                $this->columns = $columns;
915
                $this->primaryKeys = $primaryKeys;
916
                $this->primaryKeysAutoIncrement = $primaryKeysAutoIncrement;
917
            }
918
919
            /**
920
             * @param bool $isNew
921
             *
922
             * @return $this
923
             */
924
            public function setIsNew(bool $isNew): BaseEntity
925
            {
926
                $this->isNew = $isNew;
927
928
                return $this;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this returns the type anonymous//tests/Unit/Dm...actRepositoryTest.php$0 which is incompatible with the documented return type Janisbiz\LightOrm\Tests\...\AbstractRepositoryTest.
Loading history...
929
            }
930
931
            /**
932
             * @param bool $isSaved
933
             *
934
             * @return $this
935
             */
936
            public function setIsSaved(bool $isSaved): BaseEntity
937
            {
938
                $this->isSaved = $isSaved;
939
940
                return $this;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this returns the type anonymous//tests/Unit/Dm...actRepositoryTest.php$0 which is incompatible with the documented return type Janisbiz\LightOrm\Tests\...\AbstractRepositoryTest.
Loading history...
941
            }
942
943
            /**
944
             * @param string $key
945
             * @param array|string|int|double|null $value
946
             *
947
             * @return $this
948
             */
949
            public function setDataOriginal(string $key, $value): BaseEntity
950
            {
951
                $this->dataOriginal[$key] = $value;
952
953
                return $this;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this returns the type anonymous//tests/Unit/Dm...actRepositoryTest.php$0 which is incompatible with the documented return type Janisbiz\LightOrm\Tests\...\AbstractRepositoryTest.
Loading history...
954
            }
955
        };
956
    }
957
}
958