Passed
Push — master ( 3f50e7...6ba545 )
by Janis
03:02
created

testPaginatorWhenCurrentPageIsLessThanOne()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 14
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 8
nc 1
nop 0
dl 0
loc 14
rs 10
c 0
b 0
f 0
1
<?php declare(strict_types=1);
2
3
namespace Janisbiz\LightOrm\Tests\Unit\Repository;
4
5
use Janisbiz\LightOrm\Connection\ConnectionInterface;
6
use Janisbiz\LightOrm\Connection\ConnectionInvalidArgumentException;
7
use Janisbiz\LightOrm\ConnectionPool;
8
use Janisbiz\LightOrm\Paginator\PaginatorInterface;
9
use Janisbiz\LightOrm\QueryBuilder\QueryBuilderInterface;
10
use Janisbiz\LightOrm\Repository\AbstractRepository;
11
use Janisbiz\LightOrm\Repository\RepositoryException;
12
use Janisbiz\LightOrm\Tests\Unit\ReflectionTrait;
13
use PHPUnit\Framework\TestCase;
14
use Psr\Log\LogLevel;
15
use Psr\Log\NullLogger;
16
17
class AbstractRepositoryTest extends TestCase
18
{
19
    use ReflectionTrait;
20
21
    const DATABASE_NAME = 'database_name';
22
23
    const CONSTANT = 'constant_value';
24
    const CONSTANT_NAME = 'CONSTANT';
25
    const CONSTANT_NAME_NON_EXISTENT = 'CONSTANT_NON_EXISTENT';
26
27
    const VALUE_INVALID = [];
28
29
    const QUERY_BUILDER_COUNT_RESULT = 5;
30
31
    const PAGINATOR_PAGE = 1;
32
    const PAGINATOR_PAGE_INVALID = 0;
33
    const PAGINATOR_PAGE_FIRST_PAGE = 1;
34
    const PAGINATOR_PAGE_SIZE = 2;
35
    const PAGINATOR_PAGE_SIZE_INVALID = 0;
36
    const PAGINATOR_PAGE_SIZE_FIRST_PAGE = 1;
37
38
    /**
39
     * @var ConnectionInterface|\PHPUnit_Framework_MockObject_MockObject
40
     */
41
    private $connection;
42
43
    /**
44
     * @var \PDOStatement|\PHPUnit_Framework_MockObject_MockObject
45
     */
46
    private $pdoStatement;
47
48
    /**
49
     * @var QueryBuilderInterface|\PHPUnit_Framework_MockObject_MockObject
50
     */
51
    private $queryBuilder;
52
53
    /**
54
     * @var AbstractRepository|\PHPUnit_Framework_MockObject_MockObject
55
     */
56
    private $abstractRepository;
57
58
    /**
59
     * @var \ReflectionMethod
60
     */
61
    private $abstractRepositoryQuoteMethod;
62
63
    /**
64
     * @var \ReflectionMethod
65
     */
66
    private $abstractRepositoryPaginatorMethod;
67
68
    /**
69
     * @var \ReflectionMethod
70
     */
71
    private $abstractRepositoryLogMethod;
72
73
    /**
74
     * @var \ReflectionMethod
75
     */
76
    private $abstractRepositoryBeginTransactionMethod;
77
78
    /**
79
     * @var \ReflectionMethod
80
     */
81
    private $abstractRepositoryCommitMethod;
82
83
    /**
84
     * @var \ReflectionMethod
85
     */
86
    private $abstractRepositoryRollBackMethod;
87
88
    /**
89
     * @var \ReflectionMethod
90
     */
91
    private $abstractRepositoryPrepareAndExecuteMethod;
92
93
    /**
94
     * @var \ReflectionMethod
95
     */
96
    private $abstractRepositoryGetConnectionMethod;
97
98
    /**
99
     * @var \ReflectionMethod
100
     */
101
    private $abstractRepositoryGetModelConstantMethod;
102
103
    /**
104
     * @var ConnectionPool|\PHPUnit_Framework_MockObject_MockObject
105
     */
106
    private $connectionPool;
107
108
    /**
109
     * @var \ReflectionProperty
110
     */
111
    private $abstractRepositoryConnectionPoolProperty;
112
113
    public function setUp()
114
    {
115
        $this->connection = $this
116
            ->createPartialMock(
117
                ConnectionInterface::class,
118
                [
119
                    'beginTransaction',
120
                    'inTransaction',
121
                    'quote',
122
                    'commit',
123
                    'rollBack',
124
                    'prepare',
125
                    'execute',
126
                ]
127
            )
128
        ;
129
130
        $this->pdoStatement = $this->createMock(\PDOStatement::class);
131
132
        $this->queryBuilder = $this->createMock(QueryBuilderInterface::class);
133
134
        $this->abstractRepository = $this->getMockForAbstractClass(
135
            AbstractRepository::class,
136
            [],
137
            '',
138
            true,
139
            true,
140
            true,
141
            [
142
                'getEntityClass',
143
            ]
144
        );
145
        $this->abstractRepository->method('getEntityClass')->willReturn(static::class);
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

145
        $this->abstractRepository->/** @scrutinizer ignore-call */ 
146
                                   method('getEntityClass')->willReturn(static::class);

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...
146
147
        $this->abstractRepositoryQuoteMethod = $this->createAccessibleMethod($this->abstractRepository, 'quote');
148
        $this->abstractRepositoryPaginatorMethod = $this
149
            ->createAccessibleMethod($this->abstractRepository, 'paginator')
150
        ;
151
        $this->abstractRepositoryLogMethod = $this->createAccessibleMethod($this->abstractRepository, 'log');
152
        $this->abstractRepositoryBeginTransactionMethod = $this
153
            ->createAccessibleMethod($this->abstractRepository, 'beginTransaction')
154
        ;
155
        $this->abstractRepositoryCommitMethod = $this->createAccessibleMethod($this->abstractRepository, 'commit');
156
        $this->abstractRepositoryRollBackMethod = $this->createAccessibleMethod($this->abstractRepository, 'rollBack');
157
        $this->abstractRepositoryPrepareAndExecuteMethod = $this
158
            ->createAccessibleMethod($this->abstractRepository, 'prepareAndExecute')
159
        ;
160
        $this->abstractRepositoryGetConnectionMethod = $this
161
            ->createAccessibleMethod($this->abstractRepository, 'getConnection')
162
        ;
163
        $this->abstractRepositoryGetModelConstantMethod = $this
164
            ->createAccessibleMethod($this->abstractRepository, 'getEntityClassConstant')
165
        ;
166
167
        $this->connectionPool = $this->createMock(ConnectionPool::class);
168
        $this->connectionPool->method('getConnection')->willReturn($this->connection);
169
170
        $this->abstractRepositoryConnectionPoolProperty = $this
171
            ->createAccessibleProperty($this->abstractRepository, 'connectionPool')
172
        ;
173
        $this->abstractRepositoryConnectionPoolProperty->setValue($this->abstractRepository, $this->connectionPool);
174
    }
175
176
    /**
177
     * @dataProvider quoteData
178
     *
179
     * @param null|int|string|double|bool $value
180
     */
181
    public function testQuote($value)
182
    {
183
        $this->connection->expects($this->once())->method('quote');
184
185
        $this->abstractRepositoryQuoteMethod->invoke($this->abstractRepository, $value);
186
    }
187
188
    /**
189
     * @return array
190
     */
191
    public function quoteData()
192
    {
193
        return [
194
            [
195
                null,
196
            ],
197
            [
198
                0,
199
            ],
200
            [
201
                'string',
202
            ],
203
            [
204
                0.0,
205
            ],
206
            [
207
                true,
208
            ],
209
        ];
210
    }
211
212
    public function testQuoteWithInvalidValue()
213
    {
214
        $this->expectException(RepositoryException::class);
215
        $this->expectExceptionMessage('Parameter type "array" could not be quoted for SQL execution!');
216
217
        $this->abstractRepositoryQuoteMethod->invoke($this->abstractRepository, static::VALUE_INVALID);
218
    }
219
220
    public function testPaginator()
221
    {
222
        $this->queryBuilder->method('count')->willReturn(static::QUERY_BUILDER_COUNT_RESULT);
0 ignored issues
show
Bug introduced by
The method method() does not exist on Janisbiz\LightOrm\QueryB...r\QueryBuilderInterface. ( Ignorable by Annotation )

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

222
        $this->queryBuilder->/** @scrutinizer ignore-call */ 
223
                             method('count')->willReturn(static::QUERY_BUILDER_COUNT_RESULT);

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...
223
224
        $paginator = $this->abstractRepositoryPaginatorMethod->invoke(
225
            $this->abstractRepository,
226
            $this->queryBuilder,
227
            static::PAGINATOR_PAGE_SIZE,
228
            static::PAGINATOR_PAGE
229
        );
230
231
        $this->assertTrue($paginator instanceof PaginatorInterface);
232
233
        $this->abstractRepository->expects($this->once())->method('addPaginateQuery');
234
        $this->abstractRepository->expects($this->once())->method('getPaginateResult');
235
236
        $paginator->paginate();
237
    }
238
239
    public function testPaginatorWhenCurrentPageSizeIsLessThanOne()
240
    {
241
        $paginator = $this->abstractRepositoryPaginatorMethod->invoke(
242
            $this->abstractRepository,
243
            $this->queryBuilder,
244
            static::PAGINATOR_PAGE_SIZE_INVALID,
245
            static::PAGINATOR_PAGE
246
        );
247
248
        $this->assertTrue($paginator instanceof PaginatorInterface);
249
250
        $paginator->paginateFake();
251
252
        $this->assertEquals(static::PAGINATOR_PAGE_SIZE_FIRST_PAGE, $paginator->getPageSize());
253
    }
254
255
    public function testPaginatorWhenCurrentPageIsLessThanOne()
256
    {
257
        $paginator = $this->abstractRepositoryPaginatorMethod->invoke(
258
            $this->abstractRepository,
259
            $this->queryBuilder,
260
            static::PAGINATOR_PAGE_SIZE,
261
            static::PAGINATOR_PAGE_INVALID
262
        );
263
264
        $this->assertTrue($paginator instanceof PaginatorInterface);
265
266
        $paginator->paginateFake();
267
268
        $this->assertEquals(static::PAGINATOR_PAGE_FIRST_PAGE, $paginator->getCurrentPageNumber());
269
    }
270
271
    public function testLog()
272
    {
273
        $this->abstractRepository->setLogger(new NullLogger());
274
        $abstractRepository = $this->abstractRepositoryLogMethod->invoke(
275
            $this->abstractRepository,
276
            LogLevel::DEBUG,
277
            'Test Message',
278
            [
279
                'contextParam' => 'contextValue',
280
            ]
281
        );
282
283
        $this->assertTrue($abstractRepository instanceof $this->abstractRepository);
284
    }
285
286
    public function testLogWithoutLogger()
287
    {
288
        $abstractRepository = $this->abstractRepositoryLogMethod->invoke(
289
            $this->abstractRepository,
290
            LogLevel::DEBUG,
291
            'Test Message',
292
            [
293
                'contextParam' => 'contextValue',
294
            ]
295
        );
296
297
        $this->assertTrue($abstractRepository instanceof $this->abstractRepository);
298
    }
299
300
    public function testBeginTransaction()
301
    {
302
        $this->connection->expects($this->once())->method('inTransaction')->willReturn(false);
303
        $this->connection->expects($this->once())->method('beginTransaction');
304
305
        $abstractRepository = $this
306
            ->abstractRepositoryBeginTransactionMethod
307
            ->invoke($this->abstractRepository, $this->connection)
308
        ;
309
310
        $this->assertTrue($abstractRepository instanceof $this->abstractRepository);
311
    }
312
313
    public function testBeginTransactionWhenInTransaction()
314
    {
315
        $this->connection->expects($this->once())->method('inTransaction')->willReturn(true);
316
        $this->connection->expects($this->never())->method('beginTransaction');
317
318
        $abstractRepository = $this
319
            ->abstractRepositoryBeginTransactionMethod
320
            ->invoke($this->abstractRepository, $this->connection)
321
        ;
322
323
        $this->assertTrue($abstractRepository instanceof $this->abstractRepository);
324
    }
325
326
    public function testBeginTransactionWithoutConnection()
327
    {
328
        $abstractRepository = $this
329
            ->abstractRepositoryBeginTransactionMethod
330
            ->invoke($this->abstractRepository)
331
        ;
332
333
        $this->assertTrue($abstractRepository instanceof $this->abstractRepository);
334
    }
335
336
    public function testCommitWhenConnectionCommitIsSuccessful()
337
    {
338
        $this
339
            ->abstractRepositoryBeginTransactionMethod
340
            ->invoke($this->abstractRepository, $this->connection)
341
        ;
342
343
        $this->connection->method('commit')->willReturn(true);
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

343
        $this->connection->/** @scrutinizer ignore-call */ 
344
                           method('commit')->willReturn(true);

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...
344
345
        $this->assertTrue($this->abstractRepositoryCommitMethod->invoke($this->abstractRepository, $this->connection));
346
    }
347
348
    public function testCommitWhenConnectionCommitIsUnsuccessful()
349
    {
350
        $this
351
            ->abstractRepositoryBeginTransactionMethod
352
            ->invoke($this->abstractRepository, $this->connection)
353
        ;
354
355
        $this->connection->method('commit')->willReturn(false);
356
357
        $this->assertFalse($this->abstractRepositoryCommitMethod->invoke($this->abstractRepository, $this->connection));
358
    }
359
360
    public function testCommitWhenNotInTransaction()
361
    {
362
        $this->connection->expects($this->never())->method('commit');
363
364
        $this->assertTrue($this->abstractRepositoryCommitMethod->invoke($this->abstractRepository, $this->connection));
365
    }
366
367
    public function testCommitWithoutConnection()
368
    {
369
        $this
370
            ->abstractRepositoryBeginTransactionMethod
371
            ->invoke($this->abstractRepository, $this->connection)
372
        ;
373
374
        $this->connection->expects($this->once())->method('commit')->willReturn(true);
375
376
        $this->assertTrue($this->abstractRepositoryCommitMethod->invoke($this->abstractRepository));
377
    }
378
379
    public function testRollBack()
380
    {
381
        $this->connection->expects($this->once())->method('inTransaction')->willReturn(true);
382
        $this->connection->expects($this->once())->method('rollBack');
383
384
        $abstractRepository = $this
385
            ->abstractRepositoryRollBackMethod
386
            ->invoke($this->abstractRepository, $this->connection)
387
        ;
388
389
        $this->assertTrue($abstractRepository instanceof $this->abstractRepository);
390
    }
391
392
    public function testRollBackWhenNotInTransaction()
393
    {
394
        $this->connection->expects($this->once())->method('inTransaction')->willReturn(false);
395
        $this->connection->expects($this->never())->method('rollBack');
396
397
        $abstractRepository = $this
398
            ->abstractRepositoryRollBackMethod
399
            ->invoke($this->abstractRepository, $this->connection)
400
        ;
401
402
        $this->assertTrue($abstractRepository instanceof $this->abstractRepository);
403
    }
404
405
    public function testRollBackWithoutConnection()
406
    {
407
        $abstractRepository = $this
408
            ->abstractRepositoryRollBackMethod
409
            ->invoke($this->abstractRepository)
410
        ;
411
412
        $this->assertTrue($abstractRepository instanceof $this->abstractRepository);
413
    }
414
415
    public function testPrepareAndExecute()
416
    {
417
        $this->pdoStatement->expects($this->once())->method('execute');
418
        $this->connection->expects($this->once())->method('prepare')->willReturn($this->pdoStatement);
419
        $this->queryBuilder->expects($this->exactly(2))->method('buildQuery');
420
421
        $pdoStatement = $this
422
            ->abstractRepositoryPrepareAndExecuteMethod
423
            ->invoke($this->abstractRepository, $this->queryBuilder, [], $this->connection)
424
        ;
425
426
        $this->assertTrue($pdoStatement instanceof $this->pdoStatement);
427
    }
428
429
    public function testPrepareAndExecuteWithoutConnection()
430
    {
431
        $this->pdoStatement->expects($this->once())->method('execute');
432
        $this->connection->expects($this->once())->method('prepare')->willReturn($this->pdoStatement);
433
        $this->queryBuilder->expects($this->exactly(2))->method('buildQuery');
434
435
        $pdoStatement = $this
436
            ->abstractRepositoryPrepareAndExecuteMethod
437
            ->invoke($this->abstractRepository, $this->queryBuilder, [])
438
        ;
439
440
        $this->assertTrue($pdoStatement instanceof $this->pdoStatement);
441
    }
442
443
    public function testGetConnection()
444
    {
445
        $connection = $this->abstractRepositoryGetConnectionMethod->invoke($this->abstractRepository);
446
447
        $this->assertTrue($connection instanceof $this->connection);
448
    }
449
450
    public function testGetConnectionWithoutConnectionPool()
451
    {
452
        $this->abstractRepositoryConnectionPoolProperty->setValue($this->abstractRepository, null);
453
454
        $this->expectException(ConnectionInvalidArgumentException::class);
455
        $this->expectExceptionMessageRegExp('/Could not find connection by name "(.*)"\!/');
456
457
        $this->abstractRepositoryGetConnectionMethod->invoke($this->abstractRepository);
458
    }
459
460
    public function testGetModelClassConstant()
461
    {
462
        $constantValue = $this
463
            ->abstractRepositoryGetModelConstantMethod
464
            ->invoke($this->abstractRepository, static::CONSTANT_NAME)
465
        ;
466
467
        $this->assertEquals(static::CONSTANT, $constantValue);
468
    }
469
}
470