Test Failed
Pull Request — master (#1)
by Darío
07:17
created

TableGatewayTest::setUp()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 11
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

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