MyEntity   A
last analyzed

Complexity

Total Complexity 1

Size/Duplication

Total Lines 9
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 5
c 1
b 0
f 0
dl 0
loc 9
rs 10
wmc 1

1 Method

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
1
<?php
2
/**
3
 * DronePHP (http://www.dronephp.com)
4
 *
5
 * @link      http://github.com/Pleets/DronePHP
6
 * @copyright Copyright (c) 2016-2018 Pleets. (http://www.pleets.org)
7
 * @license   http://www.dronephp.com/license
8
 * @author    Darío Rivera <[email protected]>
9
 */
10
11
namespace DroneTest\Util;
12
13
use Drone\Db\Driver\MySQL;
14
use Drone\Db\Entity;
15
use Drone\Db\TableGateway\AbstractTableGateway;
16
use Drone\Db\TableGateway\TableGateway;
17
use PHPUnit\Framework\TestCase;
18
use Symfony\Component\Dotenv\Dotenv;
19
20
class TableGatewayTest extends TestCase
21
{
22
    /**
23
     * Database parameters
24
     */
25
    private $options = [
26
        "dbchar"       => "utf8",
27
        "dbport"       => "3306",
28
        "auto_connect" => false,
29
        "driver"       => 'Mysqli',  # needed for the DriverFactory
30
    ];
31
32
    public function setUp()
33
    {
34
        parent::setUp();
35
36
        $dotenv = new Dotenv();
37
        $dotenv->load(__DIR__.'/../../../.env.testing');
38
39
        $this->options['dbhost'] = $_ENV['DB_HOST'];
40
        $this->options['dbuser'] = $_ENV['DB_USER'];
41
        $this->options['dbpass'] = $_ENV['DB_PASS'];
42
        $this->options['dbname'] = $_ENV['DB_NAME'];
43
    }
44
45
    /*
46
    |--------------------------------------------------------------------------
47
    | Establishing connections
48
    |--------------------------------------------------------------------------
49
    |
50
    | The following tests are related to the connection mechanisms and its
51
    | exceptions and returned values.
52
    |
53
    */
54
55
    /**
56
     * Tests if we can connect to the database server through a TableGateway
57
     *
58
     * @return null
59
     */
60
    public function testCanEstablishConnection()
61
    {
62
        $entity = new MyEntity();
63
        $gateway = new TableGateway($entity, ["default" => $this->options]);
64
65
        $mysqliObject = $gateway->getDb()->connect();
66
67
        $this->assertInstanceOf('\mysqli', $mysqliObject);
68
        $this->assertTrue($gateway->getDb()->isConnected());
69
    }
70
71
    /**
72
     * Tests if a failed connection throws a RuntimeException when connection exists
73
     *
74
     * @expectedException RuntimeException
75
     */
76
    public function testCannotEstablishConnectionWhenExists()
77
    {
78
        $options = $this->options;
79
        $options["dbhost"] = 'myserver';   // this server does not exists
80
81
        $entity = new MyEntity();
82
        new TableGateway($entity, ["default" => $options]);
83
    }
84
85
    /**
86
     * Tests if a failed connection throws a ConnectionException
87
     *
88
     * @expectedException Drone\Db\Driver\Exception\ConnectionException
89
     */
90
    public function testCannotEstablishConnection()
91
    {
92
        $options = $this->options;
93
        $options["dbhost"] = 'myserver';   // this server does not exists
94
95
        $entity = new MyEntity();
96
        $gateway = new TableGateway($entity, ["other" => $options]);
97
98
        try {
99
            $gateway->getDb()->connect();
100
        } catch (\Exception $e) {
101
            $this->assertNotTrue($gateway->getDb()->isConnected());
102
            throw $e;
103
        }
104
    }
105
106
    /**
107
     * Tests if we get created and not created connections
108
     *
109
     * @expectedException RuntimeException
110
     */
111
    public function testGettingConnections()
112
    {
113
        $db = AbstractTableGateway::getDriver('default');
114
        $this->assertTrue(($db instanceof MySQL));
115
        $this->assertTrue($db->isConnected());
116
117
        $db = AbstractTableGateway::getDriver('other');
118
        $this->assertTrue(($db instanceof MySQL));
119
        $this->assertNotTrue($db->isConnected());
120
121
        AbstractTableGateway::getDriver('other3');
122
    }
123
124
    /**
125
     * Tests if we can create a table gateway with an existing connection
126
     *
127
     * @return null
128
     */
129
    public function testGatewayCreationWithExistingConnection()
130
    {
131
        $options = $this->options;
132
        $options["auto_connect"] = true;
133
134
        $entity = new MyEntity();
135
        $gateway = new TableGateway($entity, "default");
136
137
        $this->assertTrue($gateway->getDb()->isConnected());
138
    }
139
140
    /*
141
    |--------------------------------------------------------------------------
142
    | Querying and Transactions
143
    |--------------------------------------------------------------------------
144
    |
145
    | The following tests are related to query and transaction operations and its
146
    | exceptions and returned values.
147
    |
148
    */
149
150
    /**
151
     * Tests if we can execute DDL statements
152
     *
153
     * @return null
154
     */
155
    public function testCanExecuteDLLStatement()
156
    {
157
        $options = $this->options;
158
        $options["auto_connect"] = true;
159
160
        $entity = new MyEntity();
161
        $gateway = new MyEntityGateway($entity, "default");
162
163
        $result = $gateway->create();
164
165
        # mysqli
166
        $this->assertTrue(is_object($result));
167
168
        # properties modified by execute() method
169
        $this->assertEquals(0, $gateway->getDb()->getNumRows());
170
        $this->assertEquals(0, $gateway->getDb()->getNumFields());
171
        $this->assertEquals(0, $gateway->getDb()->getRowsAffected());
172
    }
173
174
    /**
175
     * Tests if we can execute DML statements
176
     *
177
     * @return null
178
     */
179
    public function testCanExecuteDMLStatement()
180
    {
181
        $options = $this->options;
182
        $options["auto_connect"] = true;
183
184
        $entity = new MyEntity();
185
        $gateway = new MyEntityGateway($entity, "default");
186
187
        # mysqli
188
        $result = $gateway->customDML(); // insert statement
189
190
        $this->assertTrue(is_object($result));
191
192
        # properties modified by execute() method
193
        $this->assertEquals(0, $gateway->getDb()->getNumRows());
194
        $this->assertEquals(0, $gateway->getDb()->getNumFields());
195
        $this->assertEquals(1, $gateway->getDb()->getRowsAffected());
196
    }
197
198
    /**
199
     * Tests if a wrong query execution throws an InvalidQueryException
200
     *
201
     * @expectedException Drone\Db\Driver\Exception\InvalidQueryException
202
     */
203
    public function testGettingInvalidQueryException()
204
    {
205
        $options = $this->options;
206
        $options["auto_connect"] = true;
207
208
        $entity = new MyEntity();
209
        $gateway = new MyEntityGateway($entity, "default");
210
211
        $gateway->wrongDML();
212
    }
213
214
    /**
215
     * Tests getting results
216
     *
217
     * @return null
218
     */
219
    public function testGettingResults()
220
    {
221
        $options = $this->options;
222
        $options["auto_connect"] = true;
223
224
        $entity = new MyEntity();
225
        $gateway = new MyEntityGateway($entity, "default");
226
227
        $rows = $gateway->getResults();
228
229
        # get only the first
230
        $row = array_shift($rows);
231
232
        $this->assertArrayHasKey("ID", $row);
233
        $this->assertArrayHasKey("DESCRIPTION", $row);
234
235
        # properties modified by execute() method
236
        $this->assertEquals(1, $gateway->getDb()->getNumRows());
237
        $this->assertEquals(2, $gateway->getDb()->getNumFields());
238
        $this->assertEquals(0, $gateway->getDb()->getRowsAffected());
239
    }
240
241
    # AS YOU CAN SEE IN THE ABOVE TEST, IT'S EASY TO ACCESS TO THE DRIVER (HERE MYSQL) USING THE
242
    # getDb() METHOD. A COMPLETE TEST FOR A DRIVER IS AVAILABLE IN MySQLTest.php. ALL TRANSACTION
243
    # BEHAVIOR OF TABLE GATEWAY IS RELATED TO THE DRIVER. ONLY GET THE DRIVER AND LET'S DO IT.
244
245
    /*
246
    |--------------------------------------------------------------------------
247
    | TABLE GATEWAY
248
    |--------------------------------------------------------------------------
249
    |
250
    | The following tests are related to table gateway.
251
    |
252
    */
253
254
    /**
255
     * Tests if we can execute INSERT statements through the TableGateway
256
     *
257
     * @return null
258
     */
259
    public function testINSERTING()
260
    {
261
        $options = $this->options;
262
        $options["auto_connect"] = true;
263
264
        $entity = new MyEntity();
265
266
        # Here we can use the generic table gateway or ours
267
        $gateway = new TableGateway($entity, "default");
268
269
        $result = $gateway->insert(["ID" => 500, "DESCRIPTION" => "NEW ELEMENT ONE"]);
0 ignored issues
show
Unused Code introduced by
The assignment to $result is dead and can be removed.
Loading history...
270
        $result = $gateway->insert(["ID" => 501, "DESCRIPTION" => "NEW ELEMENT TWO"]);
271
272
        $this->assertTrue(is_object($result));
273
274
        # properties modified by execute() method
275
        $this->assertEquals(0, $gateway->getDb()->getNumRows());
276
        $this->assertEquals(0, $gateway->getDb()->getNumFields());
277
278
        # here 1 is the latest affected row, could be 2 if auto_commit were false
279
        $this->assertEquals(1, $gateway->getDb()->getRowsAffected());
280
    }
281
282
    /**
283
     * Tests if no data to insert throws a LogicException
284
     *
285
     * @expectedException LogicException
286
     */
287
    public function testGettingLogicExceptionInEmptyInsertStatement()
288
    {
289
        $options = $this->options;
290
        $options["auto_connect"] = true;
291
292
        $entity = new MyEntity();
293
        $gateway = new MyEntityGateway($entity, "default");
294
295
        $gateway->insert([]);
296
    }
297
298
    /**
299
     * Tests if we can execute UPDATE statements through the TableGateway
300
     *
301
     * @return null
302
     */
303
    public function testUPDATING()
304
    {
305
        $options = $this->options;
306
        $options["auto_connect"] = true;
307
308
        $entity = new MyEntity();
309
310
        # Here we can use the generic table gateway or ours
311
        $gateway = new TableGateway($entity, "default");
312
313
        $result = $gateway->update(["DESCRIPTION" => "NEW ELEMENT MODIFIED"], ["ID" => 500]);
314
315
        $this->assertTrue(is_object($result));
316
317
        # properties modified by execute() method
318
        $this->assertEquals(0, $gateway->getDb()->getNumRows());
319
        $this->assertEquals(0, $gateway->getDb()->getNumFields());
320
        $this->assertEquals(1, $gateway->getDb()->getRowsAffected());
321
    }
322
323
    /**
324
     * Tests if no SET clause throws a LogicException in update statements
325
     *
326
     * @expectedException LogicException
327
     */
328
    public function testGettingLogicExceptionWhenUpdatingWithoutSETClause()
329
    {
330
        $options = $this->options;
331
        $options["auto_connect"] = true;
332
333
        $entity = new MyEntity();
334
        $gateway = new MyEntityGateway($entity, "default");
335
336
        $gateway->update([], ["ID" => 500]);
337
    }
338
339
    /**
340
     * Tests if no WHERE clause throws a SecurityException in update statements
341
     *
342
     * @expectedException Drone\Exception\SecurityException
343
     */
344
    public function testGettingSecurityExceptionWhenUpdatingWithoutWHEREClause()
345
    {
346
        $options = $this->options;
347
        $options["auto_connect"] = true;
348
349
        $entity = new MyEntity();
350
        $gateway = new MyEntityGateway($entity, "default");
351
352
        $gateway->update(["DESCRIPTION" => "NEW ELEMENT MODIFIED"], []);
353
    }
354
355
    /**
356
     * Tests if we can execute DELETE statements through the TableGateway
357
     *
358
     * @return null
359
     */
360
    public function testDELETING()
361
    {
362
        $options = $this->options;
363
        $options["auto_connect"] = true;
364
365
        $entity = new MyEntity();
366
367
        # Here we can use the generic table gateway or ours
368
        $gateway = new TableGateway($entity, "default");
369
370
        $result = $gateway->delete(["ID" => 500]);
371
372
        $this->assertTrue(is_object($result));
373
374
        # properties modified by execute() method
375
        $this->assertEquals(0, $gateway->getDb()->getNumRows());
376
        $this->assertEquals(0, $gateway->getDb()->getNumFields());
377
        $this->assertEquals(1, $gateway->getDb()->getRowsAffected());
378
    }
379
380
    /**
381
     * Tests if no WHERE clause throws a SecurityException in delete statements
382
     *
383
     * @expectedException Drone\Exception\SecurityException
384
     */
385
    public function testGettingSecurityExceptionWhenDeletingWithoutWHEREClause()
386
    {
387
        $options = $this->options;
388
        $options["auto_connect"] = true;
389
390
        $entity = new MyEntity();
391
        $gateway = new MyEntityGateway($entity, "default");
392
393
        $gateway->delete([]);
394
    }
395
396
    /**
397
     * Tests if we can execute SELECT statements through the TableGateway
398
     *
399
     * @return null
400
     */
401
    public function testSELECTING()
402
    {
403
        $options = $this->options;
404
        $options["auto_connect"] = true;
405
406
        $entity = new MyEntity();
407
408
        # Here we can use the generic table gateway or ours
409
        $gateway = new TableGateway($entity, "default");
410
411
        $rows = $gateway->select(["ID" => 501]);
412
413
        $this->assertTrue(is_array($rows));
414
415
        # get only the first
416
        $row = array_shift($rows);
417
418
        $this->assertArrayHasKey("ID", $row);
419
        $this->assertArrayHasKey("DESCRIPTION", $row);
420
421
        # properties modified by execute() method
422
        $this->assertEquals(1, $gateway->getDb()->getNumRows());
423
        $this->assertEquals(2, $gateway->getDb()->getNumFields());
424
        $this->assertEquals(0, $gateway->getDb()->getRowsAffected());
425
426
        $this->endTests();
427
    }
428
429
    /**
430
     * Function to leave all in order, you can execute tests again without problems.
431
     *
432
     * @return null
433
     */
434
    private function endTests()
435
    {
436
        $options = $this->options;
437
        $options["auto_connect"] = true;
438
439
        $entity = new MyEntity();
440
        $gateway = new MyEntityGateway($entity, "default");
441
442
        # remove all work
443
        $gateway->drop();
444
    }
445
}
446
447
class MyEntity extends Entity
448
{
449
    public $ID;
450
    public $DESCRIPTION;
451
452
    public function __construct($data = [])
453
    {
454
        parent::__construct($data);
455
        $this->setTableName("MYTABLE");
456
    }
457
}
458
459
class MyEntityGateway extends TableGateway
460
{
461
    public function create()
462
    {
463
        $sql = "CREATE TABLE MYTABLE (ID INTEGER(11) NOT NULL PRIMARY KEY AUTO_INCREMENT, DESCRIPTION VARCHAR(100))";
464
465
        return $this->getDb()->execute($sql);
466
    }
467
468
    public function drop()
469
    {
470
        $sql = "DROP TABLE MYTABLE";
471
472
        return $this->getDb()->execute($sql);
473
    }
474
475
    public function customDML()
476
    {
477
        $sql = "INSERT INTO MYTABLE VALUES(1000, 'Some data')";
478
479
        return $this->getDb()->execute($sql);
480
    }
481
482
    public function wrongDML()
483
    {
484
        $sql = "INSERT INTO MYTABLE (DESCRIPTION, WRONG) VALUES ('Hello world!')";
485
486
        return $this->getDb()->execute($sql);
487
    }
488
489
    public function getResults()
490
    {
491
        $sql = "SELECT * FROM MYTABLE WHERE ID = 1000";
492
        $this->getDb()->execute($sql);
493
494
        return $this->getDb()->getArrayResult();
495
    }
496
}
497