Completed
Push — 2.x ( 23eca8...741cb0 )
by Frank
01:13
created

AwsS3V3AdapterTest::s3Client()   A

Complexity

Conditions 6
Paths 5

Size

Total Lines 19

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 19
rs 9.0111
c 0
b 0
f 0
cc 6
nc 5
nop 0
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\UnableToDeleteFile;
16
use League\Flysystem\UnableToMoveFile;
17
18
/**
19
 * @group aws
20
 */
21
class AwsS3V3AdapterTest extends FilesystemAdapterTestCase
22
{
23
    /**
24
     * @var bool
25
     */
26
    private $shouldCleanUp = false;
27
28
    /**
29
     * @var string
30
     */
31
    private static $adapterPrefix = 'test-prefix';
32
33
    /**
34
     * @var S3ClientInterface|null
35
     */
36
    private static $s3Client;
37
38
    /**
39
     * @var S3ClientStub
40
     */
41
    private static $stubS3Client;
42
43
    public static function setUpBeforeClass(): void
44
    {
45
        static::$adapterPrefix = 'travis-ci/' . bin2hex(random_bytes(10));
0 ignored issues
show
Bug introduced by
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...
46
    }
47
48
    protected function tearDown(): void
49
    {
50
        if ( ! $this->shouldCleanUp) {
51
            return;
52
        }
53
54
        $adapter = $this->adapter();
55
        /** @var StorageAttributes[] $listing */
56
        $listing = $adapter->listContents('', false);
57
58
        foreach ($listing as $item) {
59
            if ($item->isFile()) {
60
                $adapter->delete($item->path());
61
            } else {
62
                $adapter->deleteDirectory($item->path());
63
            }
64
        }
65
    }
66
67
    private static function s3Client(): S3ClientInterface
68
    {
69
        if (static::$s3Client instanceof S3ClientInterface) {
0 ignored issues
show
Bug introduced by
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...
70
            return static::$s3Client;
0 ignored issues
show
Bug introduced by
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...
71
        }
72
73
        $key = getenv('FLYSYSTEM_AWS_S3_KEY');
74
        $secret = getenv('FLYSYSTEM_AWS_S3_SECRET');
75
        $bucket = getenv('FLYSYSTEM_AWS_S3_BUCKET');
76
        $region = getenv('FLYSYSTEM_AWS_S3_REGION') ?: 'eu-central-1';
77
78
        if ( ! $key || ! $secret || ! $bucket) {
79
            self::markTestSkipped('No AWS credentials present for testing.');
80
        }
81
82
        $options = ['version' => 'latest', 'credentials' => compact('key', 'secret'), 'region' => $region];
83
84
        return static::$s3Client = new S3Client($options);
0 ignored issues
show
Bug introduced by
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...
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
        static::$stubS3Client->throwExceptionWhenExecutingCommand('CopyObject');
0 ignored issues
show
Bug introduced by
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
        $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
        static::$stubS3Client->throwExceptionWhenExecutingCommand('DeleteObject');
0 ignored issues
show
Bug introduced by
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
        $adapter->delete('path.txt');
144
    }
145
146
    /**
147
     * @test
148
     * @dataProvider casesWhereHttpStreamingInfluencesSeekability
149
     */
150
    public function streaming_reads_are_not_seekable_and_non_streaming_are(bool $streaming, bool $seekable): void
151
    {
152
        if (getenv('COMPOSER_OPTS') === '--prefer-lowest') {
153
            $this->markTestSkipped('The SDK does not support streaming in low versions.');
154
        }
155
156
        $adapter = $this->useAdapter($this->createFilesystemAdapter($streaming));
157
        $this->givenWeHaveAnExistingFile('path.txt');
158
159
        $resource = $adapter->readStream('path.txt');
160
        $metadata = stream_get_meta_data($resource);
161
        fclose($resource);
162
163
        $this->assertEquals($seekable, $metadata['seekable']);
164
    }
165
166
    public function casesWhereHttpStreamingInfluencesSeekability(): Generator
167
    {
168
        yield "not streaming reads have seekable stream" => [false, true];
169
        yield "streaming reads have non-seekable stream" => [true, false];
170
    }
171
172
    /**
173
     * @test
174
     * @dataProvider casesWhereHttpStreamingInfluencesSeekability
175
     */
176
    public function configuring_http_streaming_via_options(bool $streaming): void
177
    {
178
        $adapter = $this->useAdapter($this->createFilesystemAdapter($streaming, ['@http' => ['stream' => false]]));
179
        $this->givenWeHaveAnExistingFile('path.txt');
180
181
        $resource = $adapter->readStream('path.txt');
182
        $metadata = stream_get_meta_data($resource);
183
        fclose($resource);
184
185
        $this->assertTrue($metadata['seekable']);
186
    }
187
188
    protected static function createFilesystemAdapter(bool $streaming = true, array $options = []): FilesystemAdapter
189
    {
190
        static::$stubS3Client = new S3ClientStub(static::s3Client());
0 ignored issues
show
Bug introduced by
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...
Bug introduced by
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...
191
        /** @var string $bucket */
192
        $bucket = getenv('FLYSYSTEM_AWS_S3_BUCKET');
193
        $prefix = getenv('FLYSYSTEM_AWS_S3_PREFIX') ?: static::$adapterPrefix;
0 ignored issues
show
Bug introduced by
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...
194
195
        return new AwsS3V3Adapter(static::$stubS3Client, $bucket, $prefix, null, null, $options, $streaming);
0 ignored issues
show
Bug introduced by
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...
196
    }
197
}
198