Skip to content

Commit

Permalink
Refamped GCS stubbing
Browse files Browse the repository at this point in the history
  • Loading branch information
frankdejonge committed Jan 15, 2022
1 parent 290ba29 commit ea4542a
Show file tree
Hide file tree
Showing 8 changed files with 113 additions and 171 deletions.
18 changes: 12 additions & 6 deletions src/AdapterTestUtilities/FilesystemAdapterTestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
namespace League\Flysystem\AdapterTestUtilities;

use function is_resource;
use function iterator_to_array;
use const PHP_EOL;
use Generator;
use League\Flysystem\Config;
Expand Down Expand Up @@ -36,7 +37,7 @@ abstract class FilesystemAdapterTestCase extends TestCase
/**
* @var bool
*/
private $isUsingCustomAdapter = false;
protected $isUsingCustomAdapter = false;

public static function clearFilesystemAdapterCache(): void
{
Expand Down Expand Up @@ -78,8 +79,8 @@ protected function useAdapter(FilesystemAdapter $adapter): FilesystemAdapter
*/
public function cleanupAdapter(): void
{
$this->clearStorage();
$this->clearCustomAdapter();
$this->clearStorage();
}

public function clearStorage(): void
Expand Down Expand Up @@ -331,6 +332,10 @@ public function checking_if_a_directory_exists_after_creating_it(): void
$adapter = $this->adapter();
$adapter->createDirectory('explicitly-created-directory', new Config());
self::assertTrue($adapter->directoryExists('explicitly-created-directory'));
$adapter->deleteDirectory('explicitly-created-directory');
$l = iterator_to_array($adapter->listContents('/', false), false);
self::assertEquals([], $l);
self::assertFalse($adapter->directoryExists('explicitly-created-directory'));
});
}

Expand Down Expand Up @@ -718,17 +723,18 @@ public function creating_a_directory(): void
$this->runScenario(function () {
$adapter = $this->adapter();

$adapter->createDirectory('path', new Config());
$adapter->createDirectory('creating_a_directory/path', new Config());

// Creating a directory should be idempotent.
$adapter->createDirectory('path', new Config());
$adapter->createDirectory('creating_a_directory/path', new Config());

$contents = iterator_to_array($adapter->listContents('', false));
$contents = iterator_to_array($adapter->listContents('creating_a_directory', false));
$this->assertCount(1, $contents, $this->formatIncorrectListingCount($contents));
/** @var DirectoryAttributes $directory */
$directory = $contents[0];
$this->assertInstanceOf(DirectoryAttributes::class, $directory);
$this->assertEquals('path', $directory->path());
$this->assertEquals('creating_a_directory/path', $directory->path());
$adapter->deleteDirectory('creating_a_directory/path');
});
}

Expand Down
11 changes: 9 additions & 2 deletions src/GoogleCloudStorage/GoogleCloudStorageAdapter.php
Original file line number Diff line number Diff line change
Expand Up @@ -191,15 +191,22 @@ public function deleteDirectory(string $path): void
foreach ($listing as $attributes) {
$this->delete($attributes->path());
}

if ($path !== '') {
$this->delete(rtrim($path, '/') . '/');
}
} catch (Throwable $exception) {
throw UnableToDeleteDirectory::atLocation($path, '', $exception);
}
}

public function createDirectory(string $path, Config $config): void
{
$prefixedPath = rtrim($this->prefixer->prefixPath($path), '/') . '/';
$this->bucket->upload('', ['name' => $prefixedPath]);
$prefixedPath = $this->prefixer->prefixDirectoryPath($path);

if ($prefixedPath !== '') {
$this->bucket->upload('', ['name' => $prefixedPath]);
}
}

public function setVisibility(string $path, string $visibility): void
Expand Down
39 changes: 22 additions & 17 deletions src/GoogleCloudStorage/GoogleCloudStorageAdapterTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use League\Flysystem\AdapterTestUtilities\FilesystemAdapterTestCase;
use League\Flysystem\Config;
use League\Flysystem\FilesystemAdapter;
use League\Flysystem\PathPrefixer;
use League\Flysystem\UnableToDeleteDirectory;
use League\Flysystem\UnableToDeleteFile;
use League\Flysystem\UnableToRetrieveMetadata;
Expand All @@ -21,15 +22,23 @@ class GoogleCloudStorageAdapterTest extends FilesystemAdapterTestCase
* @var string
*/
private static $adapterPrefix = 'ci';

/**
* @var StubBucket
*/
private static $bucket;
private static StubRiggedBucket $bucket;
private static PathPrefixer $prefixer;

public static function setUpBeforeClass(): void
{
static::$adapterPrefix = 'ci/' . bin2hex(random_bytes(10));
static::$adapterPrefix = 'frank-ci'; // . bin2hex(random_bytes(10));
static::$prefixer = new PathPrefixer(static::$adapterPrefix);
}

public function prefixPath(string $path): string
{
return static::$prefixer->prefixPath($path);
}

public function prefixDirectoryPath(string $path): string
{
return static::$prefixer->prefixDirectoryPath($path);
}

protected static function createFilesystemAdapter(): FilesystemAdapter
Expand All @@ -44,12 +53,7 @@ protected static function createFilesystemAdapter(): FilesystemAdapter

];
$storageClient = new StubStorageClient($clientOptions);
$connection = $storageClient->connection();
$projectId = $storageClient->projectId();

static::$bucket = $bucket = new StubBucket($connection, 'flysystem', [
'requesterProjectId' => $projectId,
]);
static::$bucket = $bucket = $storageClient->bucket('flysystem');

return new GoogleCloudStorageAdapter($bucket, static::$adapterPrefix);
}
Expand All @@ -62,7 +66,7 @@ public function fetching_visibility_of_non_existing_file(): void
$this->markTestSkipped("
Not relevant for this adapter since it's a missing ACL,
which turns into a 404 which is the expected outcome
of a private visibility. 🤷‍♂️
of a private visibility. ¯\_(ツ)_/¯
");
}

Expand All @@ -89,7 +93,7 @@ public function listing_a_toplevel_directory(): void
public function failing_to_write_a_file(): void
{
$adapter = $this->adapter();
static::$bucket->failOnUpload();
static::$bucket->failForUpload($this->prefixPath('something.txt'));

$this->expectException(UnableToWriteFile::class);

Expand All @@ -102,7 +106,7 @@ public function failing_to_write_a_file(): void
public function failing_to_delete_a_file(): void
{
$adapter = $this->adapter();
static::$bucket->withObject(static::$adapterPrefix . '/filename.txt')->failWhenDeleting();
static::$bucket->failForObject($this->prefixPath('filename.txt'));

$this->expectException(UnableToDeleteFile::class);

Expand All @@ -116,7 +120,8 @@ public function failing_to_delete_a_directory(): void
{
$adapter = $this->adapter();
$this->givenWeHaveAnExistingFile('dir/filename.txt');
static::$bucket->withObject(static::$adapterPrefix . '/dir/filename.txt')->failWhenDeleting();

static::$bucket->failForObject($this->prefixPath('dir/filename.txt'));

$this->expectException(UnableToDeleteDirectory::class);

Expand All @@ -129,7 +134,7 @@ public function failing_to_delete_a_directory(): void
public function failing_to_retrieve_visibility(): void
{
$adapter = $this->adapter();
static::$bucket->withObject(static::$adapterPrefix . '/filename.txt')->failWhenAccessingAcl();
static::$bucket->failForObject($this->prefixPath('filename.txt'));

$this->expectException(UnableToRetrieveMetadata::class);

Expand Down
64 changes: 0 additions & 64 deletions src/GoogleCloudStorage/StubBucket.php

This file was deleted.

73 changes: 0 additions & 73 deletions src/GoogleCloudStorage/StubObject.php

This file was deleted.

55 changes: 55 additions & 0 deletions src/GoogleCloudStorage/StubRiggedBucket.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<?php

declare(strict_types=1);

namespace League\Flysystem\GoogleCloudStorage;

use Google\Cloud\Storage\Bucket;
use LogicException;
use Throwable;

use function array_key_exists;

class StubRiggedBucket extends Bucket
{
private array $triggers = [];

public function failForObject($name, ?Throwable $throwable = null): void
{
$this->setupTrigger('object', $name, $throwable);
}

public function failForUpload($name, ?Throwable $throwable = null): void
{
$this->setupTrigger('upload', $name, $throwable);
}

public function object($name, array $options = [])
{
$this->pushTrigger('object', $name);

return parent::object($name, $options);
}

public function upload($data, array $options = [])
{
$this->pushTrigger('upload', $options['name'] ?? 'unknown-object-name');

return parent::upload($data, $options);
}

private function setupTrigger(string $method, string $name, ?Throwable $throwable): void
{
$this->triggers[$method][$name] = $throwable ?: new LogicException('unknown error');
}

private function pushTrigger(string $method, string $name): void
{
$trigger = $this->triggers[$method][$name] ?? null;

if ($trigger instanceof Throwable) {
unset($this->triggers[$method][$name]);
throw $trigger;
}
}
}
Loading

0 comments on commit ea4542a

Please sign in to comment.