FileTest::testValidateFormFailure()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 16
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 9
c 1
b 0
f 0
nc 1
nop 0
dl 0
loc 16
rs 9.9666
1
<?php
2
3
declare(strict_types=1);
4
5
namespace AbterPhp\Files\Service\Execute\Api;
6
7
use AbterPhp\Files\Domain\Entities\File as Entity;
8
use AbterPhp\Files\Domain\Entities\FileCategory;
9
use AbterPhp\Files\Orm\FileCategoryRepo;
10
use AbterPhp\Files\Orm\FileRepo as GridRepo;
11
use AbterPhp\Files\Validation\Factory\Api\File as ValidatorFactory;
12
use AbterPhp\Framework\Domain\Entities\IStringerEntity;
13
use AbterPhp\Framework\Filesystem\Uploader;
14
use Cocur\Slugify\Slugify;
15
use Opulence\Events\Dispatchers\IEventDispatcher;
16
use Opulence\Http\Requests\UploadedFile;
17
use Opulence\Orm\IUnitOfWork;
18
use Opulence\Validation\IValidator;
19
use Opulence\Validation\Rules\Errors\ErrorCollection;
20
use PHPUnit\Framework\MockObject\MockObject;
21
use PHPUnit\Framework\TestCase;
22
23
class FileTest extends TestCase
24
{
25
    /** @var File - System Under Test */
26
    protected $sut;
27
28
    /** @var GridRepo|MockObject */
29
    protected $gridRepoMock;
30
31
    /** @var ValidatorFactory|MockObject */
32
    protected $validatorFactoryMock;
33
34
    /** @var IUnitOfWork|MockObject */
35
    protected $unitOfWorkMock;
36
37
    /** @var IEventDispatcher|MockObject */
38
    protected $eventDispatcherMock;
39
40
    /** @var Slugify|MockObject */
41
    protected $slugifyMock;
42
43
    /** @var FileCategoryRepo|MockObject */
44
    protected $fileCategoryRepo;
45
46
    /** @var Uploader|MockObject */
47
    protected $uploaderMock;
48
49
    public function setUp(): void
50
    {
51
        parent::setUp();
52
53
        $this->gridRepoMock         = $this->createMock(GridRepo::class);
54
        $this->validatorFactoryMock = $this->createMock(ValidatorFactory::class);
55
        $this->unitOfWorkMock       = $this->createMock(IUnitOfWork::class);
56
        $this->eventDispatcherMock  = $this->createMock(IEventDispatcher::class);
57
        $this->slugifyMock          = $this->createMock(Slugify::class);
58
        $this->fileCategoryRepo     = $this->createMock(FileCategoryRepo::class);
59
        $this->uploaderMock         = $this->createMock(Uploader::class);
60
61
        $this->sut = new File(
62
            $this->gridRepoMock,
63
            $this->validatorFactoryMock,
64
            $this->unitOfWorkMock,
65
            $this->eventDispatcherMock,
66
            $this->slugifyMock,
67
            $this->fileCategoryRepo,
68
            $this->uploaderMock
69
        );
70
    }
71
72
    public function testCreateEntity()
73
    {
74
        $id = 'foo';
75
76
        $actualResult = $this->sut->createEntity($id);
77
78
        $this->assertInstanceOf(Entity::class, $actualResult);
79
        $this->assertSame($id, $actualResult->getId());
80
    }
81
82
    public function testCreate()
83
    {
84
        $description    = 'foo';
85
        $categoryId     = null;
86
        $filesystemName = 'bar';
87
        $publicName     = 'baz';
88
        $mime           = 'qux';
89
90
        $postData = [
91
            'description'     => $description,
92
            'category_id'     => $categoryId,
93
            'filesystem_name' => $filesystemName,
94
            'public_name'     => $publicName,
95
            'mime'            => $mime,
96
        ];
97
98
        $this->gridRepoMock->expects($this->once())->method('add');
99
        $this->eventDispatcherMock->expects($this->atLeastOnce())->method('dispatch');
100
        $this->unitOfWorkMock->expects($this->once())->method('commit');
101
        $this->slugifyMock->expects($this->any())->method('slugify')->willReturnArgument(0);
102
        $this->uploaderMock->expects($this->any())->method('getErrors')->willReturn([]);
103
104
        /** @var IStringerEntity|Entity $actualResult */
105
        $actualResult = $this->sut->create($postData, []);
106
107
        $this->assertInstanceOf(Entity::class, $actualResult);
108
        $this->assertEmpty($actualResult->getId());
109
        $this->assertSame($description, $actualResult->getDescription());
110
        $this->assertNull($actualResult->getCategory());
111
    }
112
113
    public function testCreateWithCategory()
114
    {
115
        $description    = 'foo';
116
        $categoryId     = 'a9338468-1094-4070-af03-bcdec333fea9';
117
        $filesystemName = 'bar';
118
        $publicName     = 'baz';
119
        $mime           = 'qux';
120
121
        $postData = [
122
            'description'     => $description,
123
            'category_id'     => $categoryId,
124
            'filesystem_name' => $filesystemName,
125
            'public_name'     => $publicName,
126
            'mime'            => $mime,
127
        ];
128
129
        $fileCategory = new FileCategory($categoryId, '', '', false, []);
130
131
        $this->gridRepoMock->expects($this->once())->method('add');
132
        $this->eventDispatcherMock->expects($this->atLeastOnce())->method('dispatch');
133
        $this->unitOfWorkMock->expects($this->once())->method('commit');
134
        $this->slugifyMock->expects($this->any())->method('slugify')->willReturnArgument(0);
135
        $this->uploaderMock->expects($this->any())->method('getErrors')->willReturn([]);
136
        $this->fileCategoryRepo->expects($this->any())->method('getById')->willReturn($fileCategory);
137
138
        /** @var IStringerEntity|Entity $actualResult */
139
        $actualResult = $this->sut->create($postData, []);
140
141
        $this->assertInstanceOf(Entity::class, $actualResult);
142
        $this->assertEmpty($actualResult->getId());
143
        $this->assertSame($description, $actualResult->getDescription());
144
        $this->assertSame($categoryId, $actualResult->getCategory()->getId());
145
    }
146
147
    public function testCreateDoesNotCommitIfUploadHadError()
148
    {
149
        $description    = 'foo';
150
        $categoryId     = 'a9338468-1094-4070-af03-bcdec333fea9';
151
        $filesystemName = 'bar';
152
        $publicName     = 'baz';
153
        $mime           = 'qux';
154
155
        $postData = [
156
            'description'     => $description,
157
            'category_id'     => $categoryId,
158
            'filesystem_name' => $filesystemName,
159
            'public_name'     => $publicName,
160
            'mime'            => $mime,
161
        ];
162
163
        $fileCategory = new FileCategory($categoryId, '', '', false, []);
164
165
        $this->gridRepoMock->expects($this->never())->method('add');
166
        $this->eventDispatcherMock->expects($this->never())->method('dispatch');
167
        $this->unitOfWorkMock->expects($this->never())->method('commit');
168
        $this->slugifyMock->expects($this->any())->method('slugify')->willReturnArgument(0);
169
        $this->uploaderMock->expects($this->any())->method('getErrors')->willReturn(['foo' => ['bar']]);
170
        $this->fileCategoryRepo->expects($this->any())->method('getById')->willReturn($fileCategory);
171
172
        /** @var IStringerEntity|Entity $actualResult */
173
        $actualResult = $this->sut->create($postData, []);
174
175
        $this->assertInstanceOf(Entity::class, $actualResult);
176
        $this->assertEmpty($actualResult->getId());
177
        $this->assertSame($description, $actualResult->getDescription());
178
        $this->assertSame($categoryId, $actualResult->getCategory()->getId());
179
    }
180
181
    public function testUpdate()
182
    {
183
        $id = '5c003d37-c59e-43eb-a471-e7b3c031fbeb';
184
185
        $entity = $this->sut->createEntity($id);
186
187
        $identifier     = 'bar';
188
        $description    = 'foo';
189
        $categoryId     = null;
190
        $filesystemName = 'bar';
191
        $publicName     = 'baz';
192
        $mime           = 'qux';
193
194
        $postData = [
195
            'identifier'      => $identifier,
196
            'description'     => $description,
197
            'category_id'     => $categoryId,
198
            'filesystem_name' => $filesystemName,
199
            'public_name'     => $publicName,
200
            'mime'            => $mime,
201
        ];
202
203
        $this->gridRepoMock->expects($this->never())->method('add');
204
        $this->gridRepoMock->expects($this->never())->method('delete');
205
        $this->eventDispatcherMock->expects($this->atLeastOnce())->method('dispatch');
206
        $this->unitOfWorkMock->expects($this->once())->method('commit');
207
        $this->slugifyMock->expects($this->any())->method('slugify')->willReturnArgument(0);
208
209
        $actualResult = $this->sut->update($entity, $postData, []);
210
211
        $this->assertTrue($actualResult);
212
    }
213
214
    public function testUpdateThrowsExceptionWhenCalledWithWrongEntity()
215
    {
216
        $this->expectException(\InvalidArgumentException::class);
217
218
        /** @var IStringerEntity|MockObject $entityStub */
219
        $entityStub = $this->createMock(IStringerEntity::class);
220
221
        $this->sut->update($entityStub, [], []);
222
    }
223
224
    public function testUpdateHandlesFileUpdate()
225
    {
226
        $id = '5c003d37-c59e-43eb-a471-e7b3c031fbeb';
227
228
        $entity = $this->sut->createEntity($id);
229
230
        $identifier     = 'bar';
231
        $description    = 'foo';
232
        $tmpFilename    = 'baz';
233
        $tmpFsName      = 'qux';
234
        $filename       = 'quux';
235
        $categoryId     = null;
236
        $filesystemName = 'bar';
237
        $publicName     = 'baz';
238
        $mime           = 'qux';
239
240
        $fileUploadMock = $this->createMock(UploadedFile::class);
241
        $fileUploadMock->expects($this->any())->method('getTempFilename')->willReturn($tmpFilename);
242
        $fileUploadMock->expects($this->any())->method('getFilename')->willReturn($filename);
243
244
        $postData = [
245
            'identifier'      => $identifier,
246
            'description'     => $description,
247
            'category_id'     => $categoryId,
248
            'filesystem_name' => $filesystemName,
249
            'public_name'     => $publicName,
250
            'mime'            => $mime,
251
        ];
252
        $fileData = [
253
            'file' => $fileUploadMock,
254
        ];
255
        $paths    = [
256
            'file' => $tmpFsName,
257
        ];
258
259
        $this->gridRepoMock->expects($this->any())->method('add');
260
        $this->gridRepoMock->expects($this->any())->method('delete');
261
        $this->eventDispatcherMock->expects($this->any())->method('dispatch');
262
        $this->unitOfWorkMock->expects($this->any())->method('commit');
263
        $this->slugifyMock->expects($this->any())->method('slugify')->willReturnArgument(0);
264
        $this->uploaderMock->expects($this->atLeastOnce())->method('delete');
265
        $this->uploaderMock->expects($this->atLeastOnce())->method('persist')->wilLReturn($paths);
266
267
        $actualResult = $this->sut->update($entity, $postData, $fileData);
268
269
        $this->assertTrue($actualResult);
270
        $this->assertSame($tmpFsName, $entity->getFilesystemName());
271
        $this->assertSame($tmpFilename, $entity->getPublicName());
272
    }
273
274
    public function testDelete()
275
    {
276
        $id     = 'foo';
277
        $entity = $this->sut->createEntity($id);
278
279
        $this->gridRepoMock->expects($this->once())->method('delete');
280
        $this->eventDispatcherMock->expects($this->atLeastOnce())->method('dispatch');
281
        $this->unitOfWorkMock->expects($this->once())->method('commit');
282
283
        $actualResult = $this->sut->delete($entity);
284
285
        $this->assertTrue($actualResult);
286
    }
287
288
    public function testRetrieveEntity()
289
    {
290
        $id     = 'foo';
291
        $entity = $this->sut->createEntity($id);
292
293
        $this->gridRepoMock->expects($this->once())->method('getById')->willReturn($entity);
294
295
        $actualResult = $this->sut->retrieveEntity($id);
296
297
        $this->assertSame($entity, $actualResult);
298
    }
299
300
    public function testRetrieveList()
301
    {
302
        $offset     = 0;
303
        $limit      = 2;
304
        $orders     = [];
305
        $conditions = [];
306
        $params     = [];
307
308
        $id0            = 'foo';
309
        $entity0        = $this->sut->createEntity($id0);
310
        $id1            = 'bar';
311
        $entity1        = $this->sut->createEntity($id1);
312
        $expectedResult = [$entity0, $entity1];
313
314
        $this->gridRepoMock->expects($this->once())->method('getPage')->willReturn($expectedResult);
315
316
        $actualResult = $this->sut->retrieveList($offset, $limit, $orders, $conditions, $params);
317
318
        $this->assertSame($expectedResult, $actualResult);
319
    }
320
321
    public function testValidateFormSuccess()
322
    {
323
        $postData = ['foo' => 'bar'];
324
325
        $validatorMock = $this->createMock(IValidator::class);
326
        $validatorMock->expects($this->once())->method('isValid')->with($postData)->willReturn(true);
327
        $validatorMock->expects($this->never())->method('getErrors');
328
329
        $this->validatorFactoryMock->expects($this->once())->method('createValidator')->willReturn($validatorMock);
330
331
        $result = $this->sut->validateForm($postData);
332
333
        $this->assertSame([], $result);
334
    }
335
336
    public function testValidateFormFailure()
337
    {
338
        $postData = ['foo' => 'bar'];
339
340
        $errorsStub        = new ErrorCollection();
341
        $errorsStub['foo'] = ['foo error'];
342
343
        $validatorMock = $this->createMock(IValidator::class);
344
        $validatorMock->expects($this->once())->method('isValid')->with($postData)->willReturn(false);
345
        $validatorMock->expects($this->once())->method('getErrors')->willReturn($errorsStub);
346
347
        $this->validatorFactoryMock->expects($this->once())->method('createValidator')->willReturn($validatorMock);
348
349
        $result = $this->sut->validateForm($postData);
350
351
        $this->assertSame(['foo' => ['foo error']], $result);
352
    }
353
354
    public function testValidateCreatesOnlyOneValidator()
355
    {
356
        $postData = ['foo' => 'bar'];
357
358
        $validatorMock = $this->createMock(IValidator::class);
359
        $validatorMock->expects($this->any())->method('isValid')->with($postData)->willReturn(true);
360
        $validatorMock->expects($this->any())->method('getErrors');
361
362
        $this->validatorFactoryMock->expects($this->once())->method('createValidator')->willReturn($validatorMock);
363
364
        $firstRun  = $this->sut->validateForm($postData);
365
        $secondRun = $this->sut->validateForm($postData);
366
367
        $this->assertSame($firstRun, $secondRun);
368
    }
369
}
370