Issues (3641)

Service/Flysystem/FlysystemServiceTest.php (3 issues)

1
<?php
2
3
/**
4
 * Copyright © 2016-present Spryker Systems GmbH. All rights reserved.
5
 * Use of this software requires acceptance of the Evaluation License Agreement. See LICENSE file.
6
 */
7
8
namespace SprykerTest\Service\Flysystem;
9
10
use Codeception\Configuration;
11
use Codeception\Test\Unit;
12
use Generated\Shared\Transfer\FlysystemResourceTransfer;
13
use Spryker\Service\FileSystemExtension\Dependency\Exception\FileSystemReadException;
14
use Spryker\Service\Flysystem\FlysystemDependencyProvider;
15
use Spryker\Service\Flysystem\FlysystemService;
16
use Spryker\Service\Flysystem\FlysystemServiceFactory;
17
use Spryker\Service\FlysystemLocalFileSystem\Plugin\Flysystem\LocalFilesystemBuilderPlugin;
18
use Spryker\Service\Kernel\Container;
19
use SprykerTest\Service\Flysystem\Stub\FlysystemConfigStub;
20
21
/**
22
 * Auto-generated group annotations
23
 *
24
 * @group SprykerTest
25
 * @group Service
26
 * @group Flysystem
27
 * @group FlysystemServiceTest
28
 * Add your own group annotations below this line
29
 */
30
class FlysystemServiceTest extends Unit
31
{
32
    /**
33
     * @var string
34
     */
35
    public const RESOURCE_FILE_NAME = 'fileName.jpg';
36
37
    /**
38
     * @var string
39
     */
40
    public const FILE_SYSTEM_DOCUMENT = 'customerFileSystem';
41
42
    /**
43
     * @var string
44
     */
45
    public const FILE_SYSTEM_PRODUCT_IMAGE = 'productFileSystem';
46
47
    /**
48
     * @var string
49
     */
50
    public const ROOT_DIRECTORY = 'fileSystemRoot/uploads/';
51
52
    /**
53
     * @var string
54
     */
55
    public const PATH_DOCUMENT = 'documents/';
56
57
    /**
58
     * @var string
59
     */
60
    public const PATH_PRODUCT_IMAGE = 'images/product/';
61
62
    /**
63
     * @var string
64
     */
65
    public const FILE_DOCUMENT = 'customer.txt';
66
67
    /**
68
     * @var string
69
     */
70
    public const FILE_PRODUCT_IMAGE = 'image.png';
71
72
    /**
73
     * @var string
74
     */
75
    public const FILE_CONTENT = 'Hello World';
76
77
    /**
78
     * @var \SprykerTest\Service\Flysystem\FlysystemServiceTester
79
     */
80
    protected $tester;
81
82
    /**
83
     * @var \Spryker\Service\Flysystem\FlysystemServiceInterface
84
     */
85
    protected $flysystemService;
86
87
    /**
88
     * @var string
89
     */
90
    protected $testDataFileSystemRootDirectory;
91
92
    /**
93
     * @return void
94
     */
95
    protected function setUp(): void
96
    {
97
        parent::setUp();
98
99
        $this->testDataFileSystemRootDirectory = Configuration::dataDir() . static::ROOT_DIRECTORY;
100
101
        $container = new Container();
102
        $container[FlysystemDependencyProvider::PLUGIN_COLLECTION_FILESYSTEM_BUILDER] = function (Container $container) {
103
            return [
104
                new LocalFilesystemBuilderPlugin(),
105
            ];
106
        };
107
108
        $container[FlysystemDependencyProvider::PLUGIN_COLLECTION_FLYSYSTEM] = function (Container $container) {
109
            return [];
110
        };
111
112
        $flysystemConfig = new FlysystemConfigStub();
113
114
        $flysystemFactory = new FlysystemServiceFactory();
115
        $flysystemFactory->setContainer($container);
116
        $flysystemFactory->setConfig($flysystemConfig);
117
118
        $flysystemService = new FlysystemService();
119
        $flysystemService->setFactory($flysystemFactory);
120
121
        $this->flysystemService = $flysystemService;
122
    }
123
124
    /**
125
     * @return void
126
     */
127
    protected function tearDown(): void
128
    {
129
        $this->directoryCleanup();
130
    }
131
132
    /**
133
     * @return void
134
     */
135
    public function testHasShouldReturnFalseWithNonExistingFile(): void
136
    {
137
        // Act
138
        $result = $this->flysystemService->has(
139
            static::FILE_SYSTEM_DOCUMENT,
140
            'foo/' . static::FILE_DOCUMENT,
141
        );
142
143
        // Assert
144
        $this->assertFalse($result);
145
    }
146
147
    /**
148
     * @return void
149
     */
150
    public function testHasShouldReturnTrueWithExistingFile(): void
151
    {
152
        // Arrange
153
        $this->createDocumentFile();
154
155
        // Act
156
        $result = $this->flysystemService->has(
157
            static::FILE_SYSTEM_DOCUMENT,
158
            'foo/' . static::FILE_DOCUMENT,
159
        );
160
161
        // Assert
162
        $this->assertTrue($result);
163
    }
164
165
    /**
166
     * @return void
167
     */
168
    public function testReadWithNonExistingFileShouldThrowFileSystemException(): void
169
    {
170
        // Assert
171
        $this->expectException(FileSystemReadException::class);
172
173
        // Act
174
        $contents = $this->flysystemService->read(
0 ignored issues
show
The assignment to $contents is dead and can be removed.
Loading history...
175
            static::FILE_SYSTEM_PRODUCT_IMAGE,
176
            'nonExistingFile.nil',
177
        );
178
    }
179
180
    /**
181
     * @return void
182
     */
183
    public function testReadWithExistingFileShouldReturnContent(): void
184
    {
185
        // Arrange
186
        $this->createDocumentFile();
187
188
        // Act
189
        $contents = $this->flysystemService->read(
190
            static::FILE_SYSTEM_DOCUMENT,
191
            'foo/' . static::FILE_DOCUMENT,
192
        );
193
194
        // Assert
195
        $this->assertSame(static::FILE_CONTENT, $contents);
196
    }
197
198
    /**
199
     * @return void
200
     */
201
    public function testWrite(): void
202
    {
203
        // Act
204
        $this->flysystemService->write(
205
            static::FILE_SYSTEM_DOCUMENT,
206
            'foo/' . static::FILE_DOCUMENT,
207
            static::FILE_CONTENT,
208
        );
209
210
        $file = $this->getLocalDocumentFile();
211
        $fileContent = file_get_contents($file);
212
213
        // Assert
214
        $this->assertSame(static::FILE_CONTENT, $fileContent);
215
    }
216
217
    /**
218
     * @return void
219
     */
220
    public function testDelete(): void
221
    {
222
        // Arrange
223
        $this->createDocumentFile();
224
225
        // Act
226
        $this->flysystemService->delete(
227
            static::FILE_SYSTEM_DOCUMENT,
228
            'foo/' . static::FILE_DOCUMENT,
229
        );
230
231
        $file = $this->getLocalDocumentFile();
232
233
        //Assert
234
        $this->assertFileDoesNotExist($file);
235
    }
236
237
    /**
238
     * @return void
239
     */
240
    public function testRename(): void
241
    {
242
        // Arrange
243
        $this->createDocumentFile();
244
245
        // Act
246
        $this->flysystemService->rename(
247
            static::FILE_SYSTEM_DOCUMENT,
248
            'foo/' . static::FILE_DOCUMENT,
249
            'foo/' . 'NEW_' . static::FILE_DOCUMENT,
250
        );
251
252
        $originalFile = $this->testDataFileSystemRootDirectory . static::PATH_DOCUMENT . 'foo/' . static::FILE_DOCUMENT;
253
        $renamedFile = $this->testDataFileSystemRootDirectory . static::PATH_DOCUMENT . 'foo/NEW_' . static::FILE_DOCUMENT;
254
255
        // Assert
256
        $this->assertFileDoesNotExist($originalFile);
257
        $this->assertFileExists($renamedFile);
258
    }
259
260
    /**
261
     * @return void
262
     */
263
    public function testCopy(): void
264
    {
265
        // Arrange
266
        $this->createDocumentFile();
267
268
        // Act
269
        $this->flysystemService->copy(
270
            static::FILE_SYSTEM_DOCUMENT,
271
            'foo/' . static::FILE_DOCUMENT,
272
            'foo/' . 'NEW_' . static::FILE_DOCUMENT,
273
        );
274
275
        $originalFile = $this->testDataFileSystemRootDirectory . static::PATH_DOCUMENT . 'foo/' . static::FILE_DOCUMENT;
276
        $copiedFile = $this->testDataFileSystemRootDirectory . static::PATH_DOCUMENT . 'foo/NEW_' . static::FILE_DOCUMENT;
277
278
        // Assert
279
        $this->assertFileExists($originalFile);
280
        $this->assertFileExists($copiedFile);
281
    }
282
283
    /**
284
     * @return void
285
     */
286
    public function testGetMimeType(): void
287
    {
288
        // Arrange
289
        $this->createDocumentFile();
290
291
        // Act
292
        $mimeType = $this->flysystemService->getMimetype(
293
            static::FILE_SYSTEM_DOCUMENT,
294
            'foo/' . static::FILE_DOCUMENT,
295
        );
296
297
        // Assert
298
        $this->assertSame('text/plain', $mimeType);
299
    }
300
301
    /**
302
     * @return void
303
     */
304
    public function testGetTimestamp(): void
305
    {
306
        // Arrange
307
        $timestampExpected = time();
308
        $this->createDocumentFile(null, $timestampExpected);
309
310
        // Act
311
        $timestamp = $this->flysystemService->getTimestamp(
312
            static::FILE_SYSTEM_DOCUMENT,
313
            'foo/' . static::FILE_DOCUMENT,
314
        );
315
316
        // Assert
317
        $this->assertSame($timestamp, $timestampExpected);
318
    }
319
320
    /**
321
     * @return void
322
     */
323
    public function testGetSize(): void
324
    {
325
        // Arrange
326
        $this->createDocumentFile();
327
        $file = $this->getLocalDocumentFile();
328
        $sizeExpected = filesize($file);
329
330
        // Act
331
        $size = $this->flysystemService->getSize(
332
            static::FILE_SYSTEM_DOCUMENT,
333
            'foo/' . static::FILE_DOCUMENT,
334
        );
335
336
        // Assert
337
        $this->assertSame($sizeExpected, $size);
338
    }
339
340
    /**
341
     * @return void
342
     */
343
    public function testIsPrivate(): void
344
    {
345
        // Arrange
346
        $this->createDocumentFile();
347
348
        // Act
349
        $isPrivate = $this->flysystemService->isPrivate(
350
            static::FILE_SYSTEM_DOCUMENT,
351
            'foo/' . static::FILE_DOCUMENT,
352
        );
353
354
        // Assert
355
        $this->assertFalse($isPrivate);
356
    }
357
358
    /**
359
     * @return void
360
     */
361
    public function testMarkAsPrivate(): void
362
    {
363
        // Arrange
364
        $this->createDocumentFile();
365
366
        $isPrivate = $this->flysystemService->isPrivate(
367
            static::FILE_SYSTEM_DOCUMENT,
368
            'foo/' . static::FILE_DOCUMENT,
369
        );
370
371
        $this->assertFalse($isPrivate);
372
373
        // Act
374
        $this->flysystemService->markAsPrivate(
375
            static::FILE_SYSTEM_DOCUMENT,
376
            'foo/' . static::FILE_DOCUMENT,
377
        );
378
379
        $isPrivate = $this->flysystemService->isPrivate(
380
            static::FILE_SYSTEM_DOCUMENT,
381
            'foo/' . static::FILE_DOCUMENT,
382
        );
383
384
        // Assert
385
        $this->assertTrue($isPrivate);
386
    }
387
388
    /**
389
     * @return void
390
     */
391
    public function testIsPublic(): void
392
    {
393
        // Arrange
394
        $this->createDocumentFile();
395
396
        // Act
397
        $isPrivate = $this->flysystemService->isPrivate(
398
            static::FILE_SYSTEM_DOCUMENT,
399
            'foo/' . static::FILE_DOCUMENT,
400
        );
401
402
        // Assert
403
        $this->assertFalse($isPrivate);
404
    }
405
406
    /**
407
     * @return void
408
     */
409
    public function testMarkAsPublic(): void
410
    {
411
        // Arrange
412
        $this->createDocumentFile();
413
414
        // Act
415
        $this->flysystemService->markAsPublic(
416
            static::FILE_SYSTEM_DOCUMENT,
417
            'foo/' . static::FILE_DOCUMENT,
418
        );
419
420
        $isPrivate = $this->flysystemService->isPrivate(
421
            static::FILE_SYSTEM_DOCUMENT,
422
            'foo/' . static::FILE_DOCUMENT,
423
        );
424
425
        // Assert
426
        $this->assertFalse($isPrivate);
427
    }
428
429
    /**
430
     * @return void
431
     */
432
    public function testCreateDir(): void
433
    {
434
        // Act
435
        $this->flysystemService->createDir(
436
            static::FILE_SYSTEM_DOCUMENT,
437
            'foo/bar',
438
        );
439
440
        $dir = $this->testDataFileSystemRootDirectory . static::PATH_DOCUMENT . 'foo/bar/';
441
442
        // Assert
443
        $this->assertDirectoryExists($dir);
444
    }
445
446
    /**
447
     * @return void
448
     */
449
    public function testDeleteDir(): void
450
    {
451
        // Arrange
452
        $dir = $this->testDataFileSystemRootDirectory . static::PATH_DOCUMENT . 'foo/bar';
453
        mkdir($dir, 0777, true);
454
455
        // Act
456
        $this->flysystemService->deleteDir(
457
            static::FILE_SYSTEM_DOCUMENT,
458
            'foo/bar',
459
        );
460
461
        // Assert
462
        $this->assertDirectoryDoesNotExist($dir);
463
    }
464
465
    /**
466
     * @return void
467
     */
468
    public function testReadStream(): void
469
    {
470
        // Arrange
471
        $this->createDocumentFile();
472
473
        // Act
474
        $stream = $this->flysystemService->readStream(
475
            static::FILE_SYSTEM_DOCUMENT,
476
            'foo/' . static::FILE_DOCUMENT,
477
        );
478
479
        $content = stream_get_contents($stream);
480
        if ($stream !== false) {
481
            fclose($stream);
482
        }
483
484
        // Assert
485
        $this->assertSame(static::FILE_CONTENT, $content);
486
    }
487
488
    /**
489
     * @return void
490
     */
491
    public function testUpdateStream(): void
492
    {
493
        // Arrange
494
        $this->createDocumentFile();
495
        $this->createDocumentFileInRoot('Lorem Ipsum');
496
497
        $file = $this->testDataFileSystemRootDirectory . static::FILE_DOCUMENT;
498
        $stream = fopen($file, 'r+');
499
500
        // Act
501
        $this->flysystemService->writeStream(
502
            static::FILE_SYSTEM_DOCUMENT,
503
            'foo/' . static::FILE_DOCUMENT,
504
            $stream,
505
        );
506
507
        if ($stream !== false) {
508
            fclose($stream);
509
        }
510
511
        $file = $this->getLocalDocumentFile();
512
        $content = file_get_contents($file);
513
514
        // Assert
515
        $this->assertFileExists($file);
516
        $this->assertSame('Lorem Ipsum', $content);
517
    }
518
519
    /**
520
     * @return void
521
     */
522
    public function testWriteStream(): void
523
    {
524
        // Arrange
525
        $this->createDocumentFileInRoot();
526
        $file = $this->testDataFileSystemRootDirectory . static::FILE_DOCUMENT;
527
        $stream = fopen($file, 'r+');
528
529
        // Act
530
        $this->flysystemService->writeStream(
531
            static::FILE_SYSTEM_DOCUMENT,
532
            'foo/' . static::FILE_DOCUMENT,
533
            $stream,
534
        );
535
536
        if ($stream !== false) {
537
            fclose($stream);
538
        }
539
540
        $file = $this->getLocalDocumentFile();
541
        $content = file_get_contents($file);
542
543
        // Assert
544
        $this->assertFileExists($file);
545
        $this->assertSame(static::FILE_CONTENT, $content);
546
    }
547
548
    /**
549
     * @return void
550
     */
551
    public function testListContents(): void
552
    {
553
        // Arrange
554
        $this->createDocumentFile();
555
556
        // Act
557
        $content = $this->flysystemService->listContents(
558
            static::FILE_SYSTEM_DOCUMENT,
559
            '/',
560
            true,
561
        );
562
563
        // Assert
564
        $this->assertGreaterThan(0, count($content));
565
    }
566
567
    /**
568
     * Tests that when a FilesystemReader returns data with properties that do not exists in the transfer object
569
     * the `AbstractTransfer::fromArray()` method will not throw an exception.
570
     *
571
     * @return void
572
     */
573
    public function testListContentsIgnoresMissingProperties(): void
574
    {
575
        // Arrange
576
        $this->tester->arrangeFilesystemProviderThatReturnsDataWithPropertiesThatAreNotPresentInTheFlysystemResourceTransfer();
577
578
        // Act
579
        $flysystemResourceTransferCollection = $this->tester->getService()->listContents('foo');
580
581
        // Assert
582
        $this->tester->assertAllInstanceOf(FlysystemResourceTransfer::class, $flysystemResourceTransferCollection);
583
    }
584
585
    /**
586
     * @param string|null $content
587
     * @param string|null $modifiedTimestamp
588
     *
589
     * @return void
590
     */
591
    protected function createDocumentFile(?string $content = null, ?string $modifiedTimestamp = null): void
592
    {
593
        $dir = $this->testDataFileSystemRootDirectory . static::PATH_DOCUMENT . 'foo';
594
        if (!is_dir($dir)) {
595
            mkdir($dir, 0777, true);
596
        }
597
598
        $file = $this->getLocalDocumentFile();
599
600
        $h = fopen($file, 'w');
601
        fwrite($h, $content ?: static::FILE_CONTENT);
602
        fclose($h);
603
604
        if ($modifiedTimestamp) {
605
            touch($file, $modifiedTimestamp);
0 ignored issues
show
$modifiedTimestamp of type string is incompatible with the type integer|null expected by parameter $mtime of touch(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

605
            touch($file, /** @scrutinizer ignore-type */ $modifiedTimestamp);
Loading history...
606
        }
607
    }
608
609
    /**
610
     * @param string|null $content
611
     * @param string|null $modifiedTimestamp
612
     *
613
     * @return void
614
     */
615
    protected function createDocumentFileInRoot(?string $content = null, ?string $modifiedTimestamp = null): void
616
    {
617
        $file = $this->testDataFileSystemRootDirectory . static::FILE_DOCUMENT;
618
619
        $h = fopen($file, 'w');
620
        fwrite($h, $content ?: static::FILE_CONTENT);
621
        fclose($h);
622
623
        if ($modifiedTimestamp) {
624
            touch($file, $modifiedTimestamp);
0 ignored issues
show
$modifiedTimestamp of type string is incompatible with the type integer|null expected by parameter $mtime of touch(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

624
            touch($file, /** @scrutinizer ignore-type */ $modifiedTimestamp);
Loading history...
625
        }
626
    }
627
628
    /**
629
     * @return string|bool
630
     */
631
    protected function getDocumentFileContent()
632
    {
633
        $file = $this->getLocalDocumentFile();
634
        if (!is_file($file)) {
635
            return false;
636
        }
637
638
        return file_get_contents($file);
639
    }
640
641
    /**
642
     * @return void
643
     */
644
    protected function directoryCleanup(): void
645
    {
646
        foreach ($this->getFileListForCleanup() as $file) {
647
            if (is_file($file)) {
648
                unlink($file);
649
            }
650
        }
651
652
        foreach ($this->getDirectoryListForCleanup() as $dir) {
653
            if (is_dir($dir)) {
654
                rmdir($dir);
655
            }
656
        }
657
    }
658
659
    /**
660
     * @return list<string>
661
     */
662
    protected function getFileListForCleanup(): array
663
    {
664
        return [
665
            $this->getLocalDocumentFile(),
666
            $this->testDataFileSystemRootDirectory . static::PATH_DOCUMENT . 'foo/NEW_' . static::FILE_DOCUMENT,
667
            $this->testDataFileSystemRootDirectory . static::PATH_PRODUCT_IMAGE . static::FILE_PRODUCT_IMAGE,
668
            $this->testDataFileSystemRootDirectory . static::FILE_DOCUMENT,
669
        ];
670
    }
671
672
    /**
673
     * @return list<string>
674
     */
675
    protected function getDirectoryListForCleanup(): array
676
    {
677
        return [
678
            $this->testDataFileSystemRootDirectory . static::PATH_DOCUMENT . 'bar',
679
            $this->testDataFileSystemRootDirectory . static::PATH_DOCUMENT . 'foo/bar',
680
            $this->testDataFileSystemRootDirectory . static::PATH_DOCUMENT . 'foo',
681
            $this->testDataFileSystemRootDirectory . static::PATH_DOCUMENT,
682
            $this->testDataFileSystemRootDirectory . static::PATH_PRODUCT_IMAGE,
683
            $this->testDataFileSystemRootDirectory . 'images/',
684
        ];
685
    }
686
687
    /**
688
     * @return string
689
     */
690
    protected function getLocalDocumentFile(): string
691
    {
692
        return $this->testDataFileSystemRootDirectory . static::PATH_DOCUMENT . 'foo/' . static::FILE_DOCUMENT;
693
    }
694
}
695