DBObjectTest::testLoadFromSQL()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 19
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 3
Bugs 0 Features 0
Metric Value
cc 1
eloc 11
c 3
b 0
f 0
nc 1
nop 0
dl 0
loc 19
rs 9.9
1
<?php
2
require_once 'stubs/Category.php';
3
4
/**
5
 * @SuppressWarnings("StaticAccess")
6
 */
7
class DBObjectTest extends \PHPUnit\Framework\TestCase
8
{
9
    protected $tableName = 'users';
10
    public function testContructor()
11
    {
12
        $classname = '\Suricate\DBObject';
13
14
        // Get mock, without the constructor being called
15
        $mock = $this->getMockBuilder($classname)
16
            ->disableOriginalConstructor()
17
            ->setMethods(array('setRelations'))
18
            ->getMockForAbstractClass();
19
20
        // set expectations for constructor calls
21
        $mock->expects($this->once())->method('setRelations');
22
23
        // now call the constructor
24
        $reflectedClass = new ReflectionClass($classname);
25
        $constructor = $reflectedClass->getConstructor();
26
        $constructor->invoke($mock);
27
    }
28
29
    public function testGetTableName()
30
    {
31
        $testName = 'my_sql_table';
32
33
        $testDBO = new \Suricate\DBObject();
34
        self::mockProperty($testDBO, 'tableName', $testName);
35
        $this->assertEquals($testName, $testDBO->getTableName());
36
    }
37
38
    public function testStaticTableName()
39
    {
40
        $this->assertEquals('categories', Category::tableName());
41
    }
42
43
    public function testGetTableIndex()
44
    {
45
        $testIndex = 'id';
46
47
        $testDBO = new \Suricate\DBObject();
48
        self::mockProperty($testDBO, 'tableIndex', $testIndex);
49
        $this->assertEquals($testIndex, $testDBO->getTableIndex());
50
    }
51
52
    public function testStaticTableIndex()
53
    {
54
        $this->assertEquals('id', Category::tableIndex());
55
    }
56
57
    public function testGetDBConfig()
58
    {
59
        $testConfigName = 'my_config';
60
61
        $testDBO = new \Suricate\DBObject();
62
        self::mockProperty($testDBO, 'DBConfig', $testConfigName);
63
        $this->assertEquals($testConfigName, $testDBO->getDBConfig());
64
    }
65
66
    public function testUndefinedGet()
67
    {
68
        $testDBO = new \Suricate\DBObject();
69
        self::mockProperty($testDBO, 'dbVariables', [
70
            'id',
71
            'name',
72
            'last_update'
73
        ]);
74
        $this->expectException(\InvalidArgumentException::class);
75
76
        $testDBO->undefinedVar;
0 ignored issues
show
Bug Best Practice introduced by
The property undefinedVar does not exist on Suricate\DBObject. Since you implemented __get, consider adding a @property annotation.
Loading history...
77
    }
78
79
    public function testDBProperty()
80
    {
81
        $testDBO = new \Suricate\DBObject();
82
        $testDBO->regularProperty = 42;
0 ignored issues
show
Bug Best Practice introduced by
The property regularProperty does not exist on Suricate\DBObject. Since you implemented __set, consider adding a @property annotation.
Loading history...
83
        self::mockProperty($testDBO, 'dbVariables', [
84
            'id',
85
            'name',
86
            'not_loaded_var'
87
        ]);
88
        self::mockProperty($testDBO, 'dbValues', [
89
            'id' => 1,
90
            'name' => 'test name'
91
        ]);
92
        $this->assertEquals($testDBO->id, 1);
0 ignored issues
show
Bug Best Practice introduced by
The property id does not exist on Suricate\DBObject. Since you implemented __get, consider adding a @property annotation.
Loading history...
93
        $this->assertNotEquals($testDBO->name, 'test name edited');
0 ignored issues
show
Bug Best Practice introduced by
The property name does not exist on Suricate\DBObject. Since you implemented __get, consider adding a @property annotation.
Loading history...
94
        $this->assertNull($testDBO->not_loaded_var);
0 ignored issues
show
Bug Best Practice introduced by
The property not_loaded_var does not exist on Suricate\DBObject. Since you implemented __get, consider adding a @property annotation.
Loading history...
95
96
        $this->assertTrue($testDBO->isDBVariable('id'));
97
        $this->assertFalse($testDBO->isDBVariable('regularProperty'));
98
99
        $this->assertTrue($testDBO->propertyExists('regularProperty'));
100
        $this->assertTrue($testDBO->propertyExists('id'));
101
        $this->assertFalse($testDBO->propertyExists('unknownProperty'));
102
    }
103
104
    public function testIsset()
105
    {
106
        $testDBO = new \Suricate\DBObject();
107
        self::mockProperty($testDBO, 'dbVariables', [
108
            'id',
109
            'name',
110
            'not_loaded_var'
111
        ]);
112
        self::mockProperty($testDBO, 'dbValues', [
113
            'id' => 1,
114
            'name' => 'test name'
115
        ]);
116
117
        $this->assertTrue(isset($testDBO->id));
0 ignored issues
show
Bug Best Practice introduced by
The property id does not exist on Suricate\DBObject. Since you implemented __get, consider adding a @property annotation.
Loading history...
118
        $this->assertFalse(isset($testDBO->undefVar));
0 ignored issues
show
Bug Best Practice introduced by
The property undefVar does not exist on Suricate\DBObject. Since you implemented __get, consider adding a @property annotation.
Loading history...
119
    }
120
121
    public function testIsLoaded()
122
    {
123
        $testIndex = 'id';
124
125
        $testDBO = new \Suricate\DBObject();
126
        self::mockProperty($testDBO, 'tableIndex', $testIndex);
127
        self::mockProperty($testDBO, 'dbVariables', [
128
            $testIndex,
129
            'name',
130
            'not_loaded_var'
131
        ]);
132
        $this->assertFalse($testDBO->isLoaded());
133
134
        self::mockProperty($testDBO, 'dbValues', [
135
            $testIndex => 1,
136
            'name' => 'test name'
137
        ]);
138
        $this->assertFalse($testDBO->isLoaded());
139
140
        $this->setupData();
141
        $dbo = $this->getDBOject();
142
        $this->assertFalse($dbo->isLoaded());
143
        $dbo->load(1);
144
        $this->assertTrue($dbo->isLoaded());
145
        $dbo->load(999);
146
        $this->assertFalse($dbo->isLoaded());
147
    }
148
149
    public function testSetLoaded()
150
    {
151
        $testIndex = 'id';
152
153
        $testDBO = new \Suricate\DBObject();
154
        self::mockProperty($testDBO, 'tableIndex', $testIndex);
155
        self::mockProperty($testDBO, 'dbVariables', [
156
            $testIndex,
157
            'name',
158
            'not_loaded_var'
159
        ]);
160
        $this->assertFalse($testDBO->isLoaded());
161
        $testDBO->setLoaded();
162
        $this->assertTrue($testDBO->isLoaded());
163
    }
164
165
    public function testProtected()
166
    {
167
        $testDBO = Category::instanciate([
168
            'id' => 1,
169
            'name' => 'test record'
170
        ]);
171
        $reflector = new ReflectionClass(Category::class);
172
        $property = $reflector->getProperty('protectedValues');
173
        $property->setAccessible(true);
174
        $this->assertSame([], $property->getValue($testDBO));
175
        $this->assertNull($testDBO->unloadable);
0 ignored issues
show
Bug Best Practice introduced by
The property unloadable does not exist on Category. Since you implemented __get, consider adding a @property annotation.
Loading history...
176
177
        $reflector = new ReflectionClass(Category::class);
178
        $property = $reflector->getProperty('protectedValues');
179
        $property->setAccessible(true);
180
        $this->assertSame([], $property->getValue($testDBO));
181
182
        $reflector = new ReflectionClass(Category::class);
183
        $property = $reflector->getProperty('loadedProtectedVariables');
184
        $property->setAccessible(true);
185
        $this->assertSame([], $property->getValue($testDBO));
186
187
        $this->assertSame(42, $testDBO->prot_var);
188
        $property = $reflector->getProperty('protectedValues');
189
        $property->setAccessible(true);
190
        $this->assertSame(['prot_var' => 42], $property->getValue($testDBO));
191
192
        $reflector = new ReflectionClass(Category::class);
193
        $property = $reflector->getProperty('loadedProtectedVariables');
194
        $property->setAccessible(true);
195
        $this->assertSame(['prot_var' => true], $property->getValue($testDBO));
196
    }
197
    public function testInstanciate()
198
    {
199
        $testDBO = Category::instanciate([
200
            'id' => 1,
201
            'name' => 'test record'
202
        ]);
203
204
        $reflector = new ReflectionClass(Category::class);
205
        $property = $reflector->getProperty('dbValues');
206
        $property->setAccessible(true);
207
        $this->assertEquals(
208
            [
209
                'id' => 1,
210
                'name' => 'test record'
211
            ],
212
            $property->getValue($testDBO)
213
        );
214
215
        $this->assertFalse($testDBO->isLoaded());
216
    }
217
218
    public function testHydrate()
219
    {
220
        $testDBO = new \Suricate\DBObject();
221
        $testDBO->realProperty = '';
0 ignored issues
show
Bug Best Practice introduced by
The property realProperty does not exist on Suricate\DBObject. Since you implemented __set, consider adding a @property annotation.
Loading history...
222
223
        self::mockProperty($testDBO, 'dbVariables', ['id', 'name']);
224
        $testDBO->hydrate([
225
            'id' => 1,
226
            'name' => 'test record',
227
            'add_column' => 'test value',
228
            'realProperty' => 'my string'
229
        ]);
230
231
        $this->assertEquals($testDBO->realProperty, 'my string');
0 ignored issues
show
Bug Best Practice introduced by
The property realProperty does not exist on Suricate\DBObject. Since you implemented __get, consider adding a @property annotation.
Loading history...
232
233
        $reflector = new ReflectionClass(get_class($testDBO));
234
        $property = $reflector->getProperty('dbValues');
235
        $property->setAccessible(true);
236
        $this->assertEquals(
237
            [
238
                'id' => 1,
239
                'name' => 'test record'
240
            ],
241
            $property->getValue($testDBO)
242
        );
243
244
        $this->assertFalse($testDBO->isLoaded());
245
    }
246
247
    public function testWakeup()
248
    {
249
        $mock = $this->getMockBuilder(\Suricate\DBObject::class)
250
            ->setMethods(['setRelations'])
251
            ->getMock();
252
253
        $mock->expects($this->once())->method('setRelations');
254
255
        $mock->__wakeup();
0 ignored issues
show
Bug introduced by
The method __wakeup() 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

255
        $mock->/** @scrutinizer ignore-call */ 
256
               __wakeup();

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...
256
    }
257
258
    public function testRelationOneOne()
259
    {
260
        $relations = [
261
            'category' => [
262
                'type' => \Suricate\DBObject::RELATION_ONE_ONE,
263
                'source' => 'category_id',
264
                'target' => 'Category'
265
            ]
266
        ];
267
        // Prepare database
268
        $this->setupData();
269
        $mock = $this->getMockBuilder(\Suricate\DBObject::class)
270
            ->setMethods(['setRelations', 'getRelation'])
271
            ->getMock();
272
273
        // Prepare setup DBObject
274
        $testDBO = $this->getDBOject();
275
        $reflector = new ReflectionClass($mock);
276
        $property = $reflector->getProperty('relations');
277
        $property->setAccessible(true);
278
        $property->setValue($testDBO, $relations);
279
280
        // get relation values
281
        $reflector = new ReflectionClass($testDBO);
282
        $relationValuesRef = $reflector->getProperty('relationValues');
283
        $relationValuesRef->setAccessible(true);
284
285
        $loadedRelationsRef = $reflector->getProperty('loadedRelations');
286
        $loadedRelationsRef->setAccessible(true);
287
288
        // Load
289
        $testDBO->load(1);
290
        $relationsValues = $relationValuesRef->getValue($testDBO);
291
        $loadedRelations = $loadedRelationsRef->getValue($testDBO);
292
293
        // No relation values at first
294
        $this->assertSame([], $relationsValues);
295
        $this->assertSame([], $loadedRelations);
296
        $this->assertEquals('Admin', $testDBO->category->name);
0 ignored issues
show
Bug Best Practice introduced by
The property category does not exist on Suricate\DBObject. Since you implemented __get, consider adding a @property annotation.
Loading history...
297
        $this->assertInstanceOf('\Suricate\DBObject', $testDBO->category);
298
299
        $relationsValues = $relationValuesRef->getValue($testDBO);
300
        $loadedRelations = $loadedRelationsRef->getValue($testDBO);
301
302
        // Check relation cache has been set
303
        $this->assertArrayHasKey('category', $relationsValues);
304
305
        // Check relation loaded flag has been set
306
        $this->assertArrayHasKey('category', $loadedRelations);
307
308
        // Check return type of relation
309
        $this->assertInstanceOf(
310
            '\Suricate\DBObject',
311
            $relationsValues['category']
312
        );
313
314
        // Load new object
315
        $testDBO = $this->getDBOject();
316
        $reflector = new ReflectionClass($mock);
317
        $property = $reflector->getProperty('relations');
318
        $property->setAccessible(true);
319
        $property->setValue($testDBO, $relations);
320
        $testDBO->load(2);
321
        // get relation values
322
        $reflector = new ReflectionClass($testDBO);
323
        $relationValuesRef = $reflector->getProperty('relationValues');
324
        $relationValuesRef->setAccessible(true);
325
326
        $loadedRelationsRef = $reflector->getProperty('loadedRelations');
327
        $loadedRelationsRef->setAccessible(true);
328
329
        $relationsValues = $relationValuesRef->getValue($testDBO);
330
        $loadedRelations = $loadedRelationsRef->getValue($testDBO);
331
332
        // No relation values at first
333
        $this->assertSame([], $relationsValues);
334
        $this->assertSame([], $loadedRelations);
335
336
        // Isset implicit load relation, check that's been loaded
337
        $this->assertTrue(isset($testDBO->category));
338
    }
339
340
    public function testLoad()
341
    {
342
        // Prepare database
343
        $this->setupData();
344
345
        // Inject database handler
346
        $testDBO = $this->getDBOject();
347
348
        $this->assertFalse($testDBO->isLoaded());
349
        $retVal = $testDBO->load(1);
350
        $this->assertTrue($testDBO->isLoaded());
351
        $this->assertEquals(1, $testDBO->id);
0 ignored issues
show
Bug Best Practice introduced by
The property id does not exist on Suricate\DBObject. Since you implemented __get, consider adding a @property annotation.
Loading history...
352
353
        $this->assertEquals('John', $testDBO->name);
0 ignored issues
show
Bug Best Practice introduced by
The property name does not exist on Suricate\DBObject. Since you implemented __get, consider adding a @property annotation.
Loading history...
354
355
        $this->assertInstanceOf('\Suricate\DBObject', $retVal);
356
    }
357
358
    public function testSaveUpdate()
359
    {
360
        // Prepare database
361
        $this->setupData();
362
363
        // Simple save
364
        $testDBO = $this->getDBOject();
365
        $testDBO->id = 55;
0 ignored issues
show
Bug Best Practice introduced by
The property id does not exist on Suricate\DBObject. Since you implemented __set, consider adding a @property annotation.
Loading history...
366
        $testDBO->name = 'Steve';
0 ignored issues
show
Bug Best Practice introduced by
The property name does not exist on Suricate\DBObject. Since you implemented __set, consider adding a @property annotation.
Loading history...
367
        $testDBO->date_added = '2019-01-27';
0 ignored issues
show
Bug Best Practice introduced by
The property date_added does not exist on Suricate\DBObject. Since you implemented __set, consider adding a @property annotation.
Loading history...
368
        $testDBO->save();
369
370
        $loaded = $this->getDBOject();
371
        $retVal = $loaded->load(55);
372
        $this->assertTrue($testDBO->isLoaded());
373
        $this->assertEquals(55, $loaded->id);
0 ignored issues
show
Bug Best Practice introduced by
The property id does not exist on Suricate\DBObject. Since you implemented __get, consider adding a @property annotation.
Loading history...
374
        $this->assertEquals('Steve', $loaded->name);
0 ignored issues
show
Bug Best Practice introduced by
The property name does not exist on Suricate\DBObject. Since you implemented __get, consider adding a @property annotation.
Loading history...
375
        $this->assertInstanceOf('\Suricate\DBObject', $retVal);
376
377
        // Update
378
        $loaded->name = 'Tim';
379
        $loaded->save();
380
        $loaded = $this->getDBOject();
381
        $retVal = $loaded->load(55);
382
        $this->assertTrue($testDBO->isLoaded());
383
        $this->assertEquals(55, $loaded->id);
384
        $this->assertEquals('Tim', $loaded->name);
385
        $this->assertInstanceOf('\Suricate\DBObject', $retVal);
386
    }
387
388
    public function testForceInsert()
389
    {
390
        // Prepare database
391
        $this->setupData();
392
393
        // Force insert
394
        $loadedForce = $this->getDBOject();
395
        $retVal = $loadedForce->load(1);
0 ignored issues
show
Unused Code introduced by
The assignment to $retVal is dead and can be removed.
Loading history...
396
        $loadedForce->id = 56;
0 ignored issues
show
Bug Best Practice introduced by
The property id does not exist on Suricate\DBObject. Since you implemented __set, consider adding a @property annotation.
Loading history...
397
        $loadedForce->save(true);
398
399
        $loaded = $this->getDBOject();
400
        $retVal = $loaded->load(56);
401
402
        $this->assertEquals(56, $loaded->id);
0 ignored issues
show
Bug Best Practice introduced by
The property id does not exist on Suricate\DBObject. Since you implemented __get, consider adding a @property annotation.
Loading history...
403
        $this->assertEquals('John', $loaded->name);
0 ignored issues
show
Bug Best Practice introduced by
The property name does not exist on Suricate\DBObject. Since you implemented __get, consider adding a @property annotation.
Loading history...
404
        $this->assertInstanceOf('\Suricate\DBObject', $retVal);
405
    }
406
407
    public function testDelete()
408
    {
409
        // Prepare database
410
        $this->setupData();
411
412
        // Simple save
413
        $testDBO = $this->getDBOject();
414
        $testDBO->id = 55;
0 ignored issues
show
Bug Best Practice introduced by
The property id does not exist on Suricate\DBObject. Since you implemented __set, consider adding a @property annotation.
Loading history...
415
        $testDBO->name = 'Steve';
0 ignored issues
show
Bug Best Practice introduced by
The property name does not exist on Suricate\DBObject. Since you implemented __set, consider adding a @property annotation.
Loading history...
416
        $testDBO->date_added = '2019-01-27';
0 ignored issues
show
Bug Best Practice introduced by
The property date_added does not exist on Suricate\DBObject. Since you implemented __set, consider adding a @property annotation.
Loading history...
417
        $testDBO->save();
418
419
        $testDBO = $this->getDBOject();
420
        $retVal = $testDBO->loadOrFail(55);
421
        $this->assertInstanceOf('\Suricate\DBObject', $retVal);
422
423
        $testDBO->delete();
424
425
        $testDBO = $this->getDBOject();
426
        $this->expectException(
427
            \Suricate\Exception\ModelNotFoundException::class
428
        );
429
        $testDBO->loadOrFail(55);
430
    }
431
432
    public function testLoadFromSQL()
433
    {
434
        // Prepare database
435
        $this->setupData();
436
437
        // Inject database handler
438
        $testDBO = $this->getDBOject();
439
440
        $sql = "SELECT * FROM `users` WHERE id=:id";
441
        $params = ['id' => 1];
442
443
        $retVal = $testDBO->loadFromSql($sql, $params);
444
        $this->assertInstanceOf('\Suricate\DBObject', $retVal);
445
        $this->assertTrue($testDBO->isLoaded());
446
447
        $params = ['id' => 100];
448
        $retVal = $testDBO->loadFromSql($sql, $params);
449
        $this->assertFalse($retVal);
450
        $this->assertFalse($testDBO->isLoaded());
451
    }
452
453
    public function testLoadOrFail()
454
    {
455
        // Prepare database
456
        $this->setupData();
457
458
        // Inject database handler
459
        $testDBO = $this->getDBOject();
460
461
        $retVal = $testDBO->loadOrFail(1);
462
        $this->assertInstanceOf('\Suricate\DBObject', $retVal);
463
464
        $this->expectException(
465
            \Suricate\Exception\ModelNotFoundException::class
466
        );
467
        $testDBO->loadOrFail(100);
468
    }
469
470
    public function testLoadOrInstanciate()
471
    {
472
        // Prepare database
473
        $this->setupData();
474
475
        $testDBO = Category::loadOrInstanciate(100);
476
477
        $comparison = $this->getCategoryDBOject();
478
        $comparison->load(100);
479
480
        $this->assertInstanceOf('\Suricate\DBObject', $testDBO);
481
        $this->assertInstanceOf('Category', $testDBO);
482
483
        $this->assertSame($comparison->id, $testDBO->id);
0 ignored issues
show
Bug Best Practice introduced by
The property id does not exist on Suricate\DBObject. Since you implemented __get, consider adding a @property annotation.
Loading history...
Bug Best Practice introduced by
The property id does not exist on Category. Since you implemented __get, consider adding a @property annotation.
Loading history...
484
        $this->assertSame($comparison->name, $testDBO->name);
0 ignored issues
show
Bug Best Practice introduced by
The property name does not exist on Category. Since you implemented __get, consider adding a @property annotation.
Loading history...
Bug Best Practice introduced by
The property name does not exist on Suricate\DBObject. Since you implemented __get, consider adding a @property annotation.
Loading history...
485
        $this->assertTrue($testDBO->isLoaded());
486
487
        // non existing
488
        $testDBO = Category::loadOrInstanciate(102);
489
        $this->assertFalse($testDBO->isLoaded()); // has been instanciated, not loaded
490
        $this->assertSame($testDBO->id, "102");
491
        $this->assertSame($testDBO->name, null);
492
493
        $testDBO = Category::loadOrInstanciate([
494
            'id' => 102,
495
            'name' => 'test name'
496
        ]);
497
        $this->assertFalse($testDBO->isLoaded());
498
        $this->assertSame($testDBO->id, "102");
499
        $this->assertSame($testDBO->name, 'test name');
500
501
        $testDBO = Category::loadOrInstanciate([
502
            'id' => 101,
503
            'name' => 'test name'
504
        ]);
505
        $this->assertFalse($testDBO->isLoaded());
506
        $this->assertSame($testDBO->id, "101");
507
        $this->assertSame($testDBO->name, 'test name');
508
509
        $testDBO = Category::loadOrInstanciate([
510
            'id' => 101,
511
            'name' => 'Employee'
512
        ]);
513
        $this->assertTrue($testDBO->isLoaded());
514
        $this->assertSame($testDBO->id, "101");
515
        $this->assertSame($testDBO->name, 'Employee');
516
    }
517
518
    public function testCreate()
519
    {
520
        // Prepare database
521
        $this->setupData();
522
        $comparison = $this->getCategoryDBOject();
523
524
        $testDBO = Category::create(['id' => 1020]);
525
526
        $this->assertInstanceOf('\Suricate\DBObject', $testDBO);
527
        $this->assertTrue($testDBO->isLoaded());
528
529
        $comparison->load(1020);
530
531
        $this->assertSame($comparison->id, $testDBO->id);
0 ignored issues
show
Bug Best Practice introduced by
The property id does not exist on Category. Since you implemented __get, consider adding a @property annotation.
Loading history...
Bug Best Practice introduced by
The property id does not exist on Suricate\DBObject. Since you implemented __get, consider adding a @property annotation.
Loading history...
532
        $this->assertSame($comparison->name, null);
0 ignored issues
show
Bug Best Practice introduced by
The property name does not exist on Suricate\DBObject. Since you implemented __get, consider adding a @property annotation.
Loading history...
533
    }
534
535
    public function testToArray()
536
    {
537
        // Prepare database
538
        $this->setupData();
539
540
        // Inject database handler
541
        $testDBO = $this->getDBOject();
542
        $testDBO->load(2);
543
544
        $this->assertSame(
545
            [
546
                'id' => '2',
547
                'category_id' => '100',
548
                'name' => 'Paul',
549
                'date_added' => '2019-01-11 00:00:00'
550
            ],
551
            $testDBO->toArray()
552
        );
553
554
        $testDBO = $this->getDBOject();
555
        $testDBO->load(2);
556
        self::mockProperty($testDBO, 'exportedVariables', [
557
            'id' => 'id',
558
            'category_id' => 'category_id,type:integer',
559
            'name' => ',omitempty',
560
            'date_added' => '-'
561
        ]);
562
        $testDBO->name = '';
0 ignored issues
show
Bug Best Practice introduced by
The property name does not exist on Suricate\DBObject. Since you implemented __set, consider adding a @property annotation.
Loading history...
563
564
        $this->assertSame(
565
            [
566
                'id' => '2',
567
                'category_id' => 100
568
            ],
569
            $testDBO->toArray()
570
        );
571
    }
572
573
    public function testToJson()
574
    {
575
        // Prepare database
576
        $this->setupData();
577
578
        // Inject database handler
579
        $testDBO = $this->getDBOject();
580
        $testDBO->load(2);
581
582
        $this->assertSame(
583
            '{"id":"2","category_id":"100","name":"Paul","date_added":"2019-01-11 00:00:00"}',
584
            $testDBO->toJson()
585
        );
586
    }
587
588
    public function testValidate()
589
    {
590
        $testDBO = $this->getDBOject();
591
        $this->assertTrue($testDBO->validate());
592
    }
593
594
    public static function mockProperty($object, string $propertyName, $value)
595
    {
596
        $reflectionClass = new \ReflectionClass($object);
597
598
        $property = $reflectionClass->getProperty($propertyName);
599
        $property->setAccessible(true);
600
        $property->setValue($object, $value);
601
        $property->setAccessible(false);
602
    }
603
604
    protected function setupData()
605
    {
606
        $pdo = new PDO('sqlite:/tmp/test.db');
607
        $pdo->exec("DROP TABLE IF EXISTS `users`");
608
        $pdo->exec("DROP TABLE IF EXISTS `categories`");
609
        $pdo->exec(
610
            "CREATE TABLE `users` (`id` INTEGER PRIMARY KEY,`category_id` INTEGER, `name` varchar(50) DEFAULT NULL,`date_added` datetime NOT NULL)"
611
        );
612
        $pdo->exec(
613
            "CREATE TABLE `categories` (`id` INTEGER PRIMARY KEY, `name` varchar(50) DEFAULT NULL, `parent_id` INTEGER DEFAULT NULL)"
614
        );
615
616
        $stmt = $pdo->prepare(
617
            "INSERT INTO `users` (name, category_id, date_added) VALUES (:name, :categoryid, :date)"
618
        );
619
        $values = [
620
            ['John', 100, '2019-01-10 00:00:00'],
621
            ['Paul', 100, '2019-01-11 00:00:00'],
622
            ['Robert', 101, '2019-01-12 00:00:00']
623
        ];
624
        foreach ($values as $value) {
625
            $stmt->execute([
626
                'name' => $value[0],
627
                'categoryid' => $value[1],
628
                'date' => $value[2]
629
            ]);
630
        }
631
632
        $stmt = $pdo->prepare(
633
            "INSERT INTO `categories` (id, name) VALUES (:id, :name)"
634
        );
635
        $values = [[100, 'Admin'], [101, 'Employee']];
636
        foreach ($values as $value) {
637
            $stmt->execute(['id' => $value[0], 'name' => $value[1]]);
638
        }
639
    }
640
641
    protected function getDatabase()
642
    {
643
        $database = new \Suricate\Database();
644
        $database->configure([
645
            'type' => 'sqlite',
646
            'file' => '/tmp/test.db'
647
        ]);
648
649
        return $database;
650
    }
651
652
    protected function getDBOject()
653
    {
654
        $dbLink = $this->getDatabase();
655
        // Inject database handler
656
        $testDBO = new \Suricate\DBObject();
657
658
        $reflector = new ReflectionClass(get_class($testDBO));
659
        $property = $reflector->getProperty('dbLink');
660
        $property->setAccessible(true);
661
        $property->setValue($testDBO, $dbLink);
662
663
        self::mockProperty($testDBO, 'tableName', $this->tableName);
664
        self::mockProperty($testDBO, 'tableIndex', 'id');
665
        self::mockProperty($testDBO, 'dbVariables', [
666
            'id',
667
            'category_id',
668
            'name',
669
            'date_added'
670
        ]);
671
672
        return $testDBO;
673
    }
674
675
    protected function getCategoryDBOject()
676
    {
677
        $dbLink = $this->getDatabase();
678
        // Inject database handler
679
        $testDBO = new \Suricate\DBObject();
680
681
        $reflector = new ReflectionClass(get_class($testDBO));
682
        $property = $reflector->getProperty('dbLink');
683
        $property->setAccessible(true);
684
        $property->setValue($testDBO, $dbLink);
685
686
        self::mockProperty($testDBO, 'tableName', 'categories');
687
        self::mockProperty($testDBO, 'tableIndex', 'id');
688
        self::mockProperty($testDBO, 'dbVariables', ['id', 'name']);
689
690
        return $testDBO;
691
    }
692
}
693