Passed
Push — master ( 9dff63...ec8207 )
by Darío
02:00
created

TableGatewayTest::testSELECTING()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 26
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

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