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

failing_to_check_for_file_existence()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 10
rs 9.9332
c 0
b 0
f 0
cc 1
nc 1
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\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
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...
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
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...
72
            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...
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
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...
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
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
        $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
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
        $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
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...
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
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...
207
        /** @var string $bucket */
208
        $bucket = getenv('FLYSYSTEM_AWS_S3_BUCKET');
209
        $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...
210
211
        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...
212
    }
213
}
214