Completed
Push — 2.x ( 741cb0...393be3 )
by Frank
01:26
created

AwsS3V3AdapterTest.php (11 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 Generator;
10
use League\Flysystem\AdapterTestUtilities\FilesystemAdapterTestCase;
11
use League\Flysystem\Config;
12
use League\Flysystem\FileAttributes;
13
use League\Flysystem\FilesystemAdapter;
14
use League\Flysystem\StorageAttributes;
15
use League\Flysystem\UnableToCheckFileExistence;
16
use League\Flysystem\UnableToDeleteFile;
17
use League\Flysystem\UnableToMoveFile;
18
19
/**
20
 * @group aws
21
 */
22
class AwsS3V3AdapterTest extends FilesystemAdapterTestCase
23
{
24
    /**
25
     * @var bool
26
     */
27
    private $shouldCleanUp = false;
28
29
    /**
30
     * @var string
31
     */
32
    private static $adapterPrefix = 'test-prefix';
33
34
    /**
35
     * @var S3ClientInterface|null
36
     */
37
    private static $s3Client;
38
39
    /**
40
     * @var S3ClientStub
41
     */
42
    private static $stubS3Client;
43
44
    public static function setUpBeforeClass(): void
45
    {
46
        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...
47
    }
48
49
    protected function tearDown(): void
50
    {
51
        if ( ! $this->shouldCleanUp) {
52
            return;
53
        }
54
55
        $adapter = $this->adapter();
56
        $adapter->deleteDirectory('/');
57
        /** @var StorageAttributes[] $listing */
58
        $listing = $adapter->listContents('', false);
59
60
        foreach ($listing as $item) {
61
            if ($item->isFile()) {
62
                $adapter->delete($item->path());
63
            } else {
64
                $adapter->deleteDirectory($item->path());
65
            }
66
        }
67
    }
68
69
    private static function s3Client(): S3ClientInterface
70
    {
71
        if (static::$s3Client instanceof S3ClientInterface) {
0 ignored issues
show
Since $s3Client is declared private, accessing it with static will lead to errors in possible sub-classes; consider using self, or increasing the visibility of $s3Client 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...
72
            return static::$s3Client;
0 ignored issues
show
Since $s3Client is declared private, accessing it with static will lead to errors in possible sub-classes; consider using self, or increasing the visibility of $s3Client 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...
73
        }
74
75
        $key = getenv('FLYSYSTEM_AWS_S3_KEY');
76
        $secret = getenv('FLYSYSTEM_AWS_S3_SECRET');
77
        $bucket = getenv('FLYSYSTEM_AWS_S3_BUCKET');
78
        $region = getenv('FLYSYSTEM_AWS_S3_REGION') ?: 'eu-central-1';
79
80
        if ( ! $key || ! $secret || ! $bucket) {
81
            self::markTestSkipped('No AWS credentials present for testing.');
82
        }
83
84
        $options = ['version' => 'latest', 'credentials' => compact('key', 'secret'), 'region' => $region];
85
86
        return static::$s3Client = new S3Client($options);
0 ignored issues
show
Since $s3Client is declared private, accessing it with static will lead to errors in possible sub-classes; consider using self, or increasing the visibility of $s3Client 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...
87
    }
88
89
    /**
90
     * @test
91
     */
92
    public function writing_with_a_specific_mime_type(): void
93
    {
94
        $adapter = $this->adapter();
95
        $adapter->write('some/path.txt', 'contents', new Config(['ContentType' => 'text/plain+special']));
96
        $mimeType = $adapter->mimeType('some/path.txt')->mimeType();
97
        $this->assertEquals('text/plain+special', $mimeType);
98
    }
99
100
    /**
101
     * @test
102
     */
103
    public function listing_contents_recursive(): void
104
    {
105
        $adapter = $this->adapter();
106
        $adapter->write('something/0/here.txt', 'contents', new Config());
107
        $adapter->write('something/1/also/here.txt', 'contents', new Config());
108
109
        $contents = iterator_to_array($adapter->listContents('', true));
110
111
        $this->assertCount(2, $contents);
112
        $this->assertContainsOnlyInstancesOf(FileAttributes::class, $contents);
113
        /** @var FileAttributes $file */
114
        $file = $contents[0];
115
        $this->assertEquals('something/0/here.txt', $file->path());
116
        /** @var FileAttributes $file */
117
        $file = $contents[1];
118
        $this->assertEquals('something/1/also/here.txt', $file->path());
119
    }
120
121
    /**
122
     * @test
123
     */
124
    public function failing_to_delete_while_moving(): void
125
    {
126
        $adapter = $this->adapter();
127
        $adapter->write('source.txt', 'contents to be copied', new Config());
128
        static::$stubS3Client->failOnNextCopy();
0 ignored issues
show
Since $stubS3Client is declared private, accessing it with static will lead to errors in possible sub-classes; consider using self, or increasing the visibility of $stubS3Client 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...
129
130
        $this->expectException(UnableToMoveFile::class);
131
132
        $adapter->move('source.txt', 'destination.txt', new Config());
133
    }
134
135
    /**
136
     * @test
137
     */
138
    public function failing_to_delete_a_file(): void
139
    {
140
        $adapter = $this->adapter();
141
        static::$stubS3Client->throwExceptionWhenExecutingCommand('DeleteObject');
0 ignored issues
show
Since $stubS3Client is declared private, accessing it with static will lead to errors in possible sub-classes; consider using self, or increasing the visibility of $stubS3Client 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...
142
143
        $this->expectException(UnableToDeleteFile::class);
144
145
        $adapter->delete('path.txt');
146
    }
147
148
    /**
149
     * @test
150
     */
151
    public function failing_to_check_for_file_existence(): void
152
    {
153
        $adapter = $this->adapter();
154
155
        static::$stubS3Client->throw500ExceptionWhenExecutingCommand('HeadObject');
0 ignored issues
show
Since $stubS3Client is declared private, accessing it with static will lead to errors in possible sub-classes; consider using self, or increasing the visibility of $stubS3Client 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...
156
157
        $this->expectException(UnableToCheckFileExistence::class);
158
159
        $adapter->fileExists('something-that-does-exist.txt');
160
    }
161
162
    /**
163
     * @test
164
     * @dataProvider casesWhereHttpStreamingInfluencesSeekability
165
     */
166
    public function streaming_reads_are_not_seekable_and_non_streaming_are(bool $streaming, bool $seekable): void
167
    {
168
        if (getenv('COMPOSER_OPTS') === '--prefer-lowest') {
169
            $this->markTestSkipped('The SDK does not support streaming in low versions.');
170
        }
171
172
        $adapter = $this->useAdapter($this->createFilesystemAdapter($streaming));
173
        $this->givenWeHaveAnExistingFile('path.txt');
174
175
        $resource = $adapter->readStream('path.txt');
176
        $metadata = stream_get_meta_data($resource);
177
        fclose($resource);
178
179
        $this->assertEquals($seekable, $metadata['seekable']);
180
    }
181
182
    public function casesWhereHttpStreamingInfluencesSeekability(): Generator
183
    {
184
        yield "not streaming reads have seekable stream" => [false, true];
185
        yield "streaming reads have non-seekable stream" => [true, false];
186
    }
187
188
    /**
189
     * @test
190
     * @dataProvider casesWhereHttpStreamingInfluencesSeekability
191
     */
192
    public function configuring_http_streaming_via_options(bool $streaming): void
193
    {
194
        $adapter = $this->useAdapter($this->createFilesystemAdapter($streaming, ['@http' => ['stream' => false]]));
195
        $this->givenWeHaveAnExistingFile('path.txt');
196
197
        $resource = $adapter->readStream('path.txt');
198
        $metadata = stream_get_meta_data($resource);
199
        fclose($resource);
200
201
        $this->assertTrue($metadata['seekable']);
202
    }
203
204
    protected static function createFilesystemAdapter(bool $streaming = true, array $options = []): FilesystemAdapter
205
    {
206
        static::$stubS3Client = new S3ClientStub(static::s3Client());
0 ignored issues
show
Since $stubS3Client is declared private, accessing it with static will lead to errors in possible sub-classes; consider using self, or increasing the visibility of $stubS3Client 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...
Since s3Client() is declared private, calling it with static will lead to errors in possible sub-classes. You can either use self, or increase the visibility of s3Client() to at least protected.

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

class YourClass
{
    private static function getTemperature() {
        return "3422 °C";
}

public static function getSomeVariable()
{
    return static::getTemperature();
}

}

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 {
      private static function getTemperature() {
        return "-182 °C";
    }
}

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

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

class YourClass
{
    private static function getTemperature() {
        return "3422 °C";
    }

    public static function getSomeVariable()
    {
        return self::getTemperature();
    }
}
Loading history...
207
        /** @var string $bucket */
208
        $bucket = getenv('FLYSYSTEM_AWS_S3_BUCKET');
209
        $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...
210
211
        return new AwsS3V3Adapter(static::$stubS3Client, $bucket, $prefix, null, null, $options, $streaming);
0 ignored issues
show
Since $stubS3Client is declared private, accessing it with static will lead to errors in possible sub-classes; consider using self, or increasing the visibility of $stubS3Client 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...
212
    }
213
}
214