testUpdateWithResources()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 57
Code Lines 42

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 42
dl 0
loc 57
rs 9.248
c 0
b 0
f 0
cc 1
nc 1
nop 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
declare(strict_types=1);
4
5
namespace AbterPhp\Admin\Orm\DataMappers;
6
7
use AbterPhp\Admin\Domain\Entities\AdminResource;
8
use AbterPhp\Admin\Domain\Entities\ApiClient;
9
use AbterPhp\Admin\TestCase\Orm\DataMapperTestCase;
10
use AbterPhp\Framework\Domain\Entities\IStringerEntity;
11
use AbterPhp\Framework\TestDouble\Database\MockStatementFactory;
12
use Opulence\Orm\Ids\Generators\IIdGenerator;
13
use PHPUnit\Framework\MockObject\MockObject;
14
15
class ApiClientSqlDataMapperTest extends DataMapperTestCase
16
{
17
    /** @var ApiClientSqlDataMapper */
18
    protected $sut;
19
20
    /** @var MockObject|IIdGenerator */
21
    protected $idGeneratorMock;
22
23
    public function setUp(): void
24
    {
25
        parent::setUp();
26
27
        $this->idGeneratorMock = $this->createMock(IIdGenerator::class);
28
29
        $this->sut = new ApiClientSqlDataMapper($this->readConnectionMock, $this->writeConnectionMock);
30
31
        $this->sut->setIdGenerator($this->idGeneratorMock);
32
    }
33
34
    public function testAdd()
35
    {
36
        $nextId      = '9b6ae58b-1aff-4344-a2ae-cda43a40674e';
37
        $userId      = '975c8746-a0e1-43fb-b74c-a331f20d130a';
38
        $description = 'foo';
39
        $secret      = 'bar';
40
41
        $sql0       = 'INSERT INTO api_clients (id, user_id, description, secret) VALUES (?, ?, ?, ?)'; // phpcs:ignore
42
        $values0    = [
43
            [$nextId, \PDO::PARAM_STR],
44
            [$userId, \PDO::PARAM_STR],
45
            [$description, \PDO::PARAM_STR],
46
            [$secret, \PDO::PARAM_STR],
47
        ];
48
        $statement0 = MockStatementFactory::createWriteStatement($this, $values0);
49
        $entity     = new ApiClient($nextId, $userId, $description, $secret);
50
51
        $this->writeConnectionMock
52
            ->expects($this->once())
53
            ->method('prepare')
54
            ->with($sql0)
55
            ->willReturn($statement0);
56
57
        $this->sut->add($entity);
58
59
        $this->assertSame($nextId, $entity->getId());
60
    }
61
62
    public function testAddWithAdminResources()
63
    {
64
        $nextId      = '9b6ae58b-1aff-4344-a2ae-cda43a40674e';
65
        $userId      = '975c8746-a0e1-43fb-b74c-a331f20d130a';
66
        $description = 'foo';
67
        $secret      = 'bar';
68
69
        $acarId0     = '4c3c3152-fc34-403e-a83e-7d7ce12b8cc4';
70
        $resourceId0 = 'e5f9d4b5-92c7-4dac-9feb-c297a7127878';
71
72
        $acarId1     = '8060491b-909f-4154-8886-62f06267c864';
73
        $resourceId1 = '5a2feca1-42dd-4bc4-81b3-9ff55da83e95';
74
75
        $this->idGeneratorMock
76
            ->expects($this->exactly(2))
77
            ->method('generate')
78
            ->willReturnOnConsecutiveCalls($acarId0, $acarId1);
79
80
        $sql0       = 'INSERT INTO api_clients (id, user_id, description, secret) VALUES (?, ?, ?, ?)'; // phpcs:ignore
81
        $values0    = [
82
            [$nextId, \PDO::PARAM_STR],
83
            [$userId, \PDO::PARAM_STR],
84
            [$description, \PDO::PARAM_STR],
85
            [$secret, \PDO::PARAM_STR],
86
        ];
87
        $statement0 = MockStatementFactory::createWriteStatement($this, $values0);
88
89
        $resource0 = new AdminResource($resourceId0, '');
90
        $resource1 = new AdminResource($resourceId1, '');
91
        $entity    = new ApiClient($nextId, $userId, $description, $secret, [$resource0, $resource1]);
92
93
        $sql1       = 'INSERT INTO api_clients_admin_resources (id, api_client_id, admin_resource_id) VALUES (?, ?, ?)'; // phpcs:ignore
94
        $values1    = [
95
            [$acarId0, \PDO::PARAM_STR],
96
            [$nextId, \PDO::PARAM_STR],
97
            [$resourceId0, \PDO::PARAM_STR],
98
        ];
99
        $statement1 = MockStatementFactory::createWriteStatement($this, $values1);
100
101
        $sql2       = 'INSERT INTO api_clients_admin_resources (id, api_client_id, admin_resource_id) VALUES (?, ?, ?)'; // phpcs:ignore
102
        $values2    = [
103
            [$acarId1, \PDO::PARAM_STR],
104
            [$nextId, \PDO::PARAM_STR],
105
            [$resourceId1, \PDO::PARAM_STR],
106
        ];
107
        $statement2 = MockStatementFactory::createWriteStatement($this, $values2);
108
109
        $this->writeConnectionMock
110
            ->expects($this->exactly(3))
111
            ->method('prepare')
112
            ->withConsecutive([$sql0], [$sql1], [$sql2])
113
            ->willReturnOnConsecutiveCalls($statement0, $statement1, $statement2);
114
115
        $this->sut->add($entity);
116
117
        $this->assertSame($nextId, $entity->getId());
118
    }
119
120
    public function testDelete()
121
    {
122
        $id          = '8fe2f659-dbe5-4995-9e07-f49fb018cfe7';
123
        $userId      = '975c8746-a0e1-43fb-b74c-a331f20d130a';
124
        $description = 'foo';
125
        $secret      = 'bar';
126
127
        $resourceId0 = 'e5f9d4b5-92c7-4dac-9feb-c297a7127878';
128
129
        $resourceId1 = '5a2feca1-42dd-4bc4-81b3-9ff55da83e95';
130
131
        $sql0       = 'DELETE FROM api_clients_admin_resources WHERE (api_client_id = ?)'; // phpcs:ignore
132
        $values0    = [[$id, \PDO::PARAM_STR]];
133
        $statement0 = MockStatementFactory::createWriteStatement($this, $values0);
134
135
        $sql1       = 'UPDATE api_clients AS api_clients SET deleted_at = NOW() WHERE (id = ?)'; // phpcs:ignore
136
        $values1    = [[$id, \PDO::PARAM_STR]];
137
        $statement1 = MockStatementFactory::createWriteStatement($this, $values1);
138
139
        $this->writeConnectionMock
140
            ->expects($this->exactly(2))
141
            ->method('prepare')
142
            ->withConsecutive([$sql0], [$sql1])
143
            ->willReturnOnConsecutiveCalls($statement0, $statement1);
144
145
        $resource0 = new AdminResource($resourceId0, '');
146
        $resource1 = new AdminResource($resourceId1, '');
147
        $entity    = new ApiClient($id, $userId, $description, $secret, [$resource0, $resource1]);
148
149
        $this->sut->delete($entity);
150
    }
151
152
    public function testGetAll()
153
    {
154
        $id0          = '24bd4165-1229-4a6e-a679-76bf90743ee1';
155
        $userId0      = '975c8746-a0e1-43fb-b74c-a331f20d130a';
156
        $description0 = 'foo';
157
        $secret0      = 'foo-secret';
158
        $id1          = '51eac0fc-2b26-4231-9559-469e59fae694';
159
        $userId1      = '27c3e7b4-d88b-4e7a-9f87-d48729842cd7';
160
        $description1 = 'bar';
161
        $secret1      = 'bar-secret';
162
163
        $sql0         = 'SELECT ac.id, ac.user_id, ac.description, ac.secret, GROUP_CONCAT(ar.id) AS admin_resource_ids, GROUP_CONCAT(ar.identifier) AS admin_resource_identifiers FROM api_clients AS ac LEFT JOIN api_clients_admin_resources AS acar ON acar.api_client_id = ac.id LEFT JOIN admin_resources AS ar ON acar.admin_resource_id = ar.id WHERE (ac.deleted_at IS NULL) GROUP BY ac.id'; // phpcs:ignore
164
        $values       = [];
165
        $expectedData = [
166
            ['id' => $id0, 'user_id' => $userId0, 'description' => $description0, 'secret' => $secret0],
167
            ['id' => $id1, 'user_id' => $userId1, 'description' => $description1, 'secret' => $secret1],
168
        ];
169
        $statement0   = MockStatementFactory::createReadStatement($this, $values, $expectedData);
170
171
        $this->readConnectionMock
172
            ->expects($this->once())
173
            ->method('prepare')
174
            ->with($sql0)
175
            ->willReturn($statement0);
176
177
        $actualResult = $this->sut->getAll();
178
179
        $this->assertCollection($expectedData, $actualResult);
180
    }
181
182
    public function testGetAllWithAdminResources()
183
    {
184
        $id0            = '24bd4165-1229-4a6e-a679-76bf90743ee1';
185
        $userId0        = '975c8746-a0e1-43fb-b74c-a331f20d130a';
186
        $description0   = 'foo';
187
        $secret0        = 'foo-secret';
188
        $arId00         = 'da9716ee-c5c1-4ea8-a762-48eb44f1df45';
189
        $arIdentifier00 = 'foo-ar0';
190
        $arId01         = 'd2d3c06c-8371-41f7-b6e0-75d8d4ac054e';
191
        $arIdentifier01 = 'foo-ar1';
192
        $id1            = '51eac0fc-2b26-4231-9559-469e59fae694';
193
        $userId1        = '27c3e7b4-d88b-4e7a-9f87-d48729842cd7';
194
        $description1   = 'bar';
195
        $secret1        = 'bar-secret';
196
        $arId10         = '';
197
        $arIdentifier10 = '';
198
199
        $sql0         = 'SELECT ac.id, ac.user_id, ac.description, ac.secret, GROUP_CONCAT(ar.id) AS admin_resource_ids, GROUP_CONCAT(ar.identifier) AS admin_resource_identifiers FROM api_clients AS ac LEFT JOIN api_clients_admin_resources AS acar ON acar.api_client_id = ac.id LEFT JOIN admin_resources AS ar ON acar.admin_resource_id = ar.id WHERE (ac.deleted_at IS NULL) GROUP BY ac.id'; // phpcs:ignore
200
        $values       = [];
201
        $expectedData = [
202
            [
203
                'id'                         => $id0,
204
                'user_id'                    => $userId0,
205
                'description'                => $description0,
206
                'secret'                     => $secret0,
207
                'admin_resource_ids'         => "$arId00,$arId01",
208
                'admin_resource_identifiers' => "$arIdentifier00,$arIdentifier01",
209
            ],
210
            [
211
                'id'                         => $id1,
212
                'user_id'                    => $userId1,
213
                'description'                => $description1,
214
                'secret'                     => $secret1,
215
                'admin_resource_ids'         => $arId10,
216
                'admin_resource_identifiers' => $arIdentifier10,
217
            ],
218
        ];
219
        $statement0   = MockStatementFactory::createReadStatement($this, $values, $expectedData);
220
221
        $this->readConnectionMock
222
            ->expects($this->once())
223
            ->method('prepare')
224
            ->with($sql0)
225
            ->willReturn($statement0);
226
227
        $actualResult = $this->sut->getAll();
228
229
        $this->assertCollection($expectedData, $actualResult);
230
    }
231
232
    public function testGetPage()
233
    {
234
        $id0          = '24bd4165-1229-4a6e-a679-76bf90743ee1';
235
        $userId0      = '975c8746-a0e1-43fb-b74c-a331f20d130a';
236
        $description0 = 'foo';
237
        $secret0      = 'foo-secret';
238
        $id1          = '51eac0fc-2b26-4231-9559-469e59fae694';
239
        $userId1      = '27c3e7b4-d88b-4e7a-9f87-d48729842cd7';
240
        $description1 = 'bar';
241
        $secret1      = 'bar-secret';
242
243
        $sql0         = 'SELECT SQL_CALC_FOUND_ROWS ac.id, ac.user_id, ac.description, ac.secret, GROUP_CONCAT(ar.id) AS admin_resource_ids, GROUP_CONCAT(ar.identifier) AS admin_resource_identifiers FROM api_clients AS ac LEFT JOIN api_clients_admin_resources AS acar ON acar.api_client_id = ac.id LEFT JOIN admin_resources AS ar ON acar.admin_resource_id = ar.id WHERE (ac.deleted_at IS NULL) GROUP BY ac.id ORDER BY created_at ASC LIMIT 10 OFFSET 0'; // phpcs:ignore
244
        $values       = [];
245
        $expectedData = [
246
            ['id' => $id0, 'user_id' => $userId0, 'description' => $description0, 'secret' => $secret0],
247
            ['id' => $id1, 'user_id' => $userId1, 'description' => $description1, 'secret' => $secret1],
248
        ];
249
        $statement0   = MockStatementFactory::createReadStatement($this, $values, $expectedData);
250
251
        $this->readConnectionMock
252
            ->expects($this->once())
253
            ->method('prepare')
254
            ->with($sql0)
255
            ->willReturn($statement0);
256
257
        $actualResult = $this->sut->getPage(0, 10, [], [], []);
258
259
        $this->assertCollection($expectedData, $actualResult);
260
    }
261
262
    public function testGetPageWithOrdersAndConditions()
263
    {
264
        $id0          = '24bd4165-1229-4a6e-a679-76bf90743ee1';
265
        $userId0      = '975c8746-a0e1-43fb-b74c-a331f20d130a';
266
        $description0 = 'foo';
267
        $secret0      = 'foo-secret';
268
        $id1          = '51eac0fc-2b26-4231-9559-469e59fae694';
269
        $userId1      = '27c3e7b4-d88b-4e7a-9f87-d48729842cd7';
270
        $description1 = 'bar';
271
        $secret1      = 'bar-secret';
272
273
        $orders     = ['ac.description ASC'];
274
        $conditions = ['ac.description LIKE \'abc%\'', 'abc.description LIKE \'%bca\''];
275
276
        $sql0         = 'SELECT SQL_CALC_FOUND_ROWS ac.id, ac.user_id, ac.description, ac.secret, GROUP_CONCAT(ar.id) AS admin_resource_ids, GROUP_CONCAT(ar.identifier) AS admin_resource_identifiers FROM api_clients AS ac LEFT JOIN api_clients_admin_resources AS acar ON acar.api_client_id = ac.id LEFT JOIN admin_resources AS ar ON acar.admin_resource_id = ar.id WHERE (ac.deleted_at IS NULL) AND (ac.description LIKE \'abc%\') AND (abc.description LIKE \'%bca\') GROUP BY ac.id ORDER BY ac.description ASC LIMIT 10 OFFSET 0'; // phpcs:ignore
277
        $values       = [];
278
        $expectedData = [
279
            ['id' => $id0, 'user_id' => $userId0, 'description' => $description0, 'secret' => $secret0],
280
            ['id' => $id1, 'user_id' => $userId1, 'description' => $description1, 'secret' => $secret1],
281
        ];
282
        $statement0   = MockStatementFactory::createReadStatement($this, $values, $expectedData);
283
284
        $this->readConnectionMock
285
            ->expects($this->once())
286
            ->method('prepare')
287
            ->with($sql0)
288
            ->willReturn($statement0);
289
290
        $actualResult = $this->sut->getPage(0, 10, $orders, $conditions, []);
291
292
        $this->assertCollection($expectedData, $actualResult);
293
    }
294
295
    public function testGetById()
296
    {
297
        $id          = '4b72daf8-81a9-400f-b865-28306d1c1646';
298
        $userId      = '975c8746-a0e1-43fb-b74c-a331f20d130a';
299
        $description = 'foo';
300
        $secret      = 'foo-secret';
301
302
        $sql0         = 'SELECT ac.id, ac.user_id, ac.description, ac.secret, GROUP_CONCAT(ar.id) AS admin_resource_ids, GROUP_CONCAT(ar.identifier) AS admin_resource_identifiers FROM api_clients AS ac LEFT JOIN api_clients_admin_resources AS acar ON acar.api_client_id = ac.id LEFT JOIN admin_resources AS ar ON acar.admin_resource_id = ar.id WHERE (ac.deleted_at IS NULL) AND (ac.id = :api_client_id) GROUP BY ac.id'; // phpcs:ignore
303
        $values       = ['api_client_id' => [$id, \PDO::PARAM_STR]];
304
        $expectedData = [['id' => $id, 'user_id' => $userId, 'description' => $description, 'secret' => $secret]];
305
        $statement0   = MockStatementFactory::createReadStatement($this, $values, $expectedData);
306
307
        $this->readConnectionMock
308
            ->expects($this->once())
309
            ->method('prepare')
310
            ->with($sql0)
311
            ->willReturn($statement0);
312
313
        $actualResult = $this->sut->getById($id);
314
315
        $this->assertEntity($expectedData[0], $actualResult);
316
    }
317
318
    public function testUpdate()
319
    {
320
        $id          = '9b6ae58b-1aff-4344-a2ae-cda43a40674e';
321
        $userId      = '975c8746-a0e1-43fb-b74c-a331f20d130a';
322
        $description = 'foo';
323
        $secret      = 'bar';
324
325
        $sql0       = 'UPDATE api_clients AS api_clients SET description = ?, secret = ? WHERE (id = ?) AND (deleted_at IS NULL)'; // phpcs:ignore
326
        $values0    = [
327
            [$description, \PDO::PARAM_STR],
328
            [$secret, \PDO::PARAM_STR],
329
            [$id, \PDO::PARAM_STR],
330
        ];
331
        $statement0 = MockStatementFactory::createWriteStatement($this, $values0);
332
333
        $sql1       = 'DELETE FROM api_clients_admin_resources WHERE (api_client_id = ?)'; // phpcs:ignore
334
        $values1    = [[$id, \PDO::PARAM_STR]];
335
        $statement1 = MockStatementFactory::createWriteStatement($this, $values1);
336
337
        $this->writeConnectionMock
338
            ->expects($this->exactly(2))
339
            ->method('prepare')
340
            ->withConsecutive([$sql0], [$sql1])
341
            ->willReturnOnConsecutiveCalls($statement0, $statement1);
342
343
        $entity = new ApiClient($id, $userId, $description, $secret);
344
        $this->sut->update($entity);
345
    }
346
347
    public function testUpdateWithResources()
348
    {
349
        $id          = '9b6ae58b-1aff-4344-a2ae-cda43a40674e';
350
        $userId      = '975c8746-a0e1-43fb-b74c-a331f20d130a';
351
        $description = 'foo';
352
        $secret      = 'bar';
353
354
        $acarId0     = '4c3c3152-fc34-403e-a83e-7d7ce12b8cc4';
355
        $resourceId0 = 'e5f9d4b5-92c7-4dac-9feb-c297a7127878';
356
357
        $acarId1     = '8060491b-909f-4154-8886-62f06267c864';
358
        $resourceId1 = '5a2feca1-42dd-4bc4-81b3-9ff55da83e95';
359
360
        $this->idGeneratorMock
361
            ->expects($this->exactly(2))
362
            ->method('generate')
363
            ->willReturnOnConsecutiveCalls($acarId0, $acarId1);
364
365
        $sql0       = 'UPDATE api_clients AS api_clients SET description = ?, secret = ? WHERE (id = ?) AND (deleted_at IS NULL)'; // phpcs:ignore
366
        $values0    = [
367
            [$description, \PDO::PARAM_STR],
368
            [$secret, \PDO::PARAM_STR],
369
            [$id, \PDO::PARAM_STR],
370
        ];
371
        $statement0 = MockStatementFactory::createWriteStatement($this, $values0);
372
373
        $sql1       = 'DELETE FROM api_clients_admin_resources WHERE (api_client_id = ?)'; // phpcs:ignore
374
        $values1    = [[$id, \PDO::PARAM_STR]];
375
        $statement1 = MockStatementFactory::createWriteStatement($this, $values1);
376
377
        $resource0 = new AdminResource($resourceId0, '');
378
        $resource1 = new AdminResource($resourceId1, '');
379
        $entity    = new ApiClient($id, $userId, $description, $secret, [$resource0, $resource1]);
380
381
        $sql2       = 'INSERT INTO api_clients_admin_resources (id, api_client_id, admin_resource_id) VALUES (?, ?, ?)'; // phpcs:ignore
382
        $values2    = [
383
            [$acarId0, \PDO::PARAM_STR],
384
            [$id, \PDO::PARAM_STR],
385
            [$resourceId0, \PDO::PARAM_STR],
386
        ];
387
        $statement2 = MockStatementFactory::createWriteStatement($this, $values2);
388
389
        $sql3       = 'INSERT INTO api_clients_admin_resources (id, api_client_id, admin_resource_id) VALUES (?, ?, ?)'; // phpcs:ignore
390
        $values3    = [
391
            [$acarId1, \PDO::PARAM_STR],
392
            [$id, \PDO::PARAM_STR],
393
            [$resourceId1, \PDO::PARAM_STR],
394
        ];
395
        $statement3 = MockStatementFactory::createWriteStatement($this, $values3);
396
397
        $this->writeConnectionMock
398
            ->expects($this->exactly(4))
399
            ->method('prepare')
400
            ->withConsecutive([$sql0], [$sql1], [$sql2], [$sql3])
401
            ->willReturnOnConsecutiveCalls($statement0, $statement1, $statement2, $statement3);
402
403
        $this->sut->update($entity);
404
    }
405
406
    public function testAddThrowsExceptionIfCalledWithInvalidEntity()
407
    {
408
        $this->expectException(\InvalidArgumentException::class);
409
410
        /** @var IStringerEntity|MockObject $entity */
411
        $entity = $this->createMock(IStringerEntity::class);
412
413
        $this->sut->add($entity);
414
    }
415
416
    public function testDeleteThrowsExceptionIfCalledWithInvalidEntity()
417
    {
418
        $this->expectException(\InvalidArgumentException::class);
419
420
        /** @var IStringerEntity|MockObject $entity */
421
        $entity = $this->createMock(IStringerEntity::class);
422
423
        $this->sut->delete($entity);
424
    }
425
426
    public function testUpdateThrowsExceptionIfCalledWithInvalidEntity()
427
    {
428
        $this->expectException(\InvalidArgumentException::class);
429
430
        /** @var IStringerEntity|MockObject $entity */
431
        $entity = $this->createMock(IStringerEntity::class);
432
433
        $this->sut->update($entity);
434
    }
435
436
    /**
437
     * @param array     $expectedData
438
     * @param ApiClient $entity
439
     */
440
    protected function assertEntity(array $expectedData, $entity)
441
    {
442
        $this->assertInstanceOf(ApiClient::class, $entity);
443
        $this->assertEquals($expectedData['id'], $entity->getId());
444
        $this->assertSame($expectedData['user_id'], $entity->getUserId());
445
        $this->assertSame($expectedData['description'], $entity->getDescription());
446
        $this->assertSame($expectedData['secret'], $entity->getSecret());
447
448
        $this->assertAdminResources($expectedData, $entity);
449
    }
450
451
    /**
452
     * @param array     $expectedData
453
     * @param ApiClient $entity
454
     */
455
    protected function assertAdminResources(array $expectedData, $entity)
456
    {
457
        if (empty($expectedData['admin_resource_ids'])) {
458
            return;
459
        }
460
461
        $arIds         = explode(',', $expectedData['admin_resource_ids']);
462
        $arIdentifiers = explode(',', $expectedData['admin_resource_identifiers']);
463
464
        foreach ($entity->getAdminResources() as $idx => $ar) {
465
            $this->assertSame($arIds[$idx], $ar->getId());
466
            $this->assertSame($arIdentifiers[$idx], $ar->getIdentifier());
467
        }
468
    }
469
}
470