Completed
Push — 2.x ( caa3e0...1848cf )
by Frank
01:38
created

AwsS3V3AdapterTest.php (2 issues)

Labels
Severity

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
3
declare(strict_types=1);
4
5
namespace League\Flysystem\AwsS3V3;
6
7
use Aws\S3\S3Client;
8
use Aws\S3\S3ClientInterface;
9
use League\Flysystem\AdapterTestUtilities\FilesystemAdapterTestCase;
10
use League\Flysystem\Config;
11
use League\Flysystem\FileAttributes;
12
use League\Flysystem\FilesystemAdapter;
13
use League\Flysystem\StorageAttributes;
14
use League\Flysystem\UnableToDeleteFile;
15
use League\Flysystem\UnableToMoveFile;
16
17
/**
18
 * @group aws
19
 */
20
class AwsS3V3AdapterTest extends FilesystemAdapterTestCase
21
{
22
    /**
23
     * @var bool
24
     */
25
    private $shouldCleanUp = false;
26
27
    /**
28
     * @var string
29
     */
30
    private static $adapterPrefix = 'test-prefix';
31
32
    /**
33
     * @var S3ClientInterface|null
34
     */
35
    private $s3Client;
36
37
    /**
38
     * @var S3ClientStub
39
     */
40
    private $stubS3Client;
41
42
    public static function setUpBeforeClass(): void
43
    {
44
        static::$adapterPrefix = 'travis-ci/' . bin2hex(random_bytes(10));
0 ignored issues
show
Since $adapterPrefix is declared private, accessing it with static will lead to errors in possible sub-classes; consider using self, or increasing the visibility of $adapterPrefix to at least protected.

Let’s assume you have a class which uses late-static binding:

class YourClass
{
    private static $someVariable;

    public static function getSomeVariable()
    {
        return static::$someVariable;
    }
}

The code above will run fine in your PHP runtime. However, if you now create a sub-class and call the getSomeVariable() on that sub-class, you will receive a runtime error:

class YourSubClass extends YourClass { }

YourSubClass::getSomeVariable(); // Will cause an access error.

In the case above, it makes sense to update SomeClass to use self instead:

class SomeClass
{
    private static $someVariable;

    public static function getSomeVariable()
    {
        return self::$someVariable; // self works fine with private.
    }
}
Loading history...
45
    }
46
47
    protected function tearDown(): void
48
    {
49
        if ( ! $this->shouldCleanUp) {
50
            return;
51
        }
52
53
        $adapter = $this->adapter();
54
        /** @var StorageAttributes[] $listing */
55
        $listing = $adapter->listContents('', false);
56
57
        foreach ($listing as $item) {
58
            if ($item->isFile()) {
59
                $adapter->delete($item->path());
60
            } else {
61
                $adapter->deleteDirectory($item->path());
62
            }
63
        }
64
    }
65
66
    private function s3Client(): S3ClientInterface
67
    {
68
        if ($this->s3Client instanceof S3ClientInterface) {
69
            return $this->s3Client;
70
        }
71
72
        $key = getenv('FLYSYSTEM_AWS_S3_KEY');
73
        $secret = getenv('FLYSYSTEM_AWS_S3_SECRET');
74
        $bucket = getenv('FLYSYSTEM_AWS_S3_BUCKET');
75
        $region = getenv('FLYSYSTEM_AWS_S3_REGION') ?: 'eu-central-1';
76
77
        if ( ! $key || ! $secret || ! $bucket) {
78
            $this->markTestSkipped('No AWS credentials present for testing.');
79
        }
80
81
        $this->shouldCleanUp = true;
82
        $options = ['version' => 'latest', 'credentials' => compact('key', 'secret'), 'region' => $region];
83
84
        return $this->s3Client = new S3Client($options);
85
    }
86
87
    /**
88
     * @test
89
     */
90
    public function writing_with_a_specific_mime_type(): void
91
    {
92
        $adapter = $this->adapter();
93
        $adapter->write('some/path.txt', 'contents', new Config(['ContentType' => 'text/plain+special']));
94
        $mimeType = $adapter->mimeType('some/path.txt')->mimeType();
95
        $this->assertEquals('text/plain+special', $mimeType);
96
    }
97
98
    /**
99
     * @test
100
     */
101
    public function listing_contents_recursive(): void
102
    {
103
        $adapter = $this->adapter();
104
        $adapter->write('something/0/here.txt', 'contents', new Config());
105
        $adapter->write('something/1/also/here.txt', 'contents', new Config());
106
107
        $contents = iterator_to_array($adapter->listContents('', true));
108
109
        $this->assertCount(2, $contents);
110
        $this->assertContainsOnlyInstancesOf(FileAttributes::class, $contents);
111
        /** @var FileAttributes $file */
112
        $file = $contents[0];
113
        $this->assertEquals('something/0/here.txt', $file->path());
114
        /** @var FileAttributes $file */
115
        $file = $contents[1];
116
        $this->assertEquals('something/1/also/here.txt', $file->path());
117
    }
118
119
    /**
120
     * @test
121
     */
122
    public function failing_to_delete_while_moving(): void
123
    {
124
        $this->expectException(UnableToMoveFile::class);
125
126
        $adapter = $this->adapter();
127
        $adapter->write('source.txt', 'contents to be copied', new Config());
128
        $this->stubS3Client->throwExceptionWhenExecutingCommand('CopyObject');
129
130
        $adapter->move('source.txt', 'destination.txt', new Config());
131
    }
132
133
    /**
134
     * @test
135
     */
136
    public function failing_to_delete_a_file(): void
137
    {
138
        $this->expectException(UnableToDeleteFile::class);
139
140
        $adapter = $this->adapter();
141
        $this->stubS3Client->throwExceptionWhenExecutingCommand('DeleteObject');
142
143
        $adapter->delete('path.txt');
144
    }
145
146
    protected function createFilesystemAdapter(): FilesystemAdapter
147
    {
148
        $this->stubS3Client = new S3ClientStub($this->s3Client());
149
        /** @var string $bucket */
150
        $bucket = getenv('FLYSYSTEM_AWS_S3_BUCKET');
151
        $prefix = getenv('FLYSYSTEM_AWS_S3_PREFIX') ?: static::$adapterPrefix;
0 ignored issues
show
Since $adapterPrefix is declared private, accessing it with static will lead to errors in possible sub-classes; consider using self, or increasing the visibility of $adapterPrefix to at least protected.

Let’s assume you have a class which uses late-static binding:

class YourClass
{
    private static $someVariable;

    public static function getSomeVariable()
    {
        return static::$someVariable;
    }
}

The code above will run fine in your PHP runtime. However, if you now create a sub-class and call the getSomeVariable() on that sub-class, you will receive a runtime error:

class YourSubClass extends YourClass { }

YourSubClass::getSomeVariable(); // Will cause an access error.

In the case above, it makes sense to update SomeClass to use self instead:

class SomeClass
{
    private static $someVariable;

    public static function getSomeVariable()
    {
        return self::$someVariable; // self works fine with private.
    }
}
Loading history...
152
153
        return new AwsS3V3Adapter($this->stubS3Client, $bucket, $prefix);
154
    }
155
}
156