Skip to content

Commit

Permalink
Test file move and copy scenarios under various visibility retention …
Browse files Browse the repository at this point in the history
…and setting configurations.
  • Loading branch information
frankdejonge committed Nov 7, 2023
1 parent 9546ca2 commit 6155cb2
Show file tree
Hide file tree
Showing 3 changed files with 182 additions and 4 deletions.
24 changes: 21 additions & 3 deletions src/Filesystem.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,13 @@

use DateTimeInterface;
use Generator;
use League\Flysystem\UrlGeneration\ShardedPrefixPublicUrlGenerator;
use League\Flysystem\UrlGeneration\PrefixPublicUrlGenerator;
use League\Flysystem\UrlGeneration\PublicUrlGenerator;
use League\Flysystem\UrlGeneration\ShardedPrefixPublicUrlGenerator;
use League\Flysystem\UrlGeneration\TemporaryUrlGenerator;
use Throwable;

use function array_key_exists;
use function is_array;

class Filesystem implements FilesystemOperator
Expand Down Expand Up @@ -119,7 +120,7 @@ private function pipeListing(string $location, bool $deep, iterable $listing): G

public function move(string $source, string $destination, array $config = []): void
{
$config = $this->config->withoutSettings(Config::OPTION_VISIBILITY)->extend($config);
$config = $this->resolveConfigForMoveAndCopy($config);
$from = $this->pathNormalizer->normalizePath($source);
$to = $this->pathNormalizer->normalizePath($destination);

Expand All @@ -138,7 +139,7 @@ public function move(string $source, string $destination, array $config = []): v

public function copy(string $source, string $destination, array $config = []): void
{
$config = $this->config->withoutSettings(Config::OPTION_VISIBILITY)->extend($config);
$config = $this->resolveConfigForMoveAndCopy($config);
$from = $this->pathNormalizer->normalizePath($source);
$to = $this->pathNormalizer->normalizePath($destination);

Expand Down Expand Up @@ -256,4 +257,21 @@ private function rewindStream($resource): void
rewind($resource);
}
}

private function resolveConfigForMoveAndCopy(array $config): Config
{
$retainVisibility = $this->config->get('retain_visibility', $config['retain_visibility'] ?? true);
$fullConfig = $this->config->extend($config);

/*
* By default, we retain visibility. When we do not retain visibility, the visibility setting
* from the default configuration is ignored. Only when it is set explicitly, we propagate the
* setting.
*/
if ($retainVisibility && ! array_key_exists(Config::OPTION_VISIBILITY, $config)) {
$fullConfig = $fullConfig->withoutSettings(Config::OPTION_VISIBILITY)->extend($config);
}

return $fullConfig;
}
}
153 changes: 153 additions & 0 deletions src/FilesystemTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -674,4 +674,157 @@ public function unable_to_get_checksum_directory(): void

$filesystem->checksum('foo');
}

/**
* @test
* @dataProvider fileMoveOrCopyScenarios
*/
public function moving_a_file_with_visibility_scenario(
array $mainConfig,
array $moveConfig,
?string $writeVisibility,
string $expectedVisibility
): void {
// arrange
$filesystem = new Filesystem(
new InMemoryFilesystemAdapter(),
$mainConfig
);
$writeConfig = $writeVisibility ? ['visibility' => $writeVisibility] : [];
$filesystem->write('from.txt', 'contents', $writeConfig);

// act
$filesystem->move('from.txt', 'to.txt', $moveConfig);

// assert
$this->assertEquals($expectedVisibility, $filesystem->visibility('to.txt'));
}

/**
* @test
* @dataProvider fileMoveOrCopyScenarios
*/
public function copying_a_file_with_visibility_scenario(
array $mainConfig,
array $copyConfig,
?string $writeVisibility,
string $expectedVisibility
): void {
// arrange
$filesystem = new Filesystem(
new InMemoryFilesystemAdapter(),
$mainConfig
);
$writeConfig = $writeVisibility ? ['visibility' => $writeVisibility] : [];
$filesystem->write('from.txt', 'contents', $writeConfig);

// act
$filesystem->copy('from.txt', 'to.txt', $copyConfig);

// assert
$this->assertEquals($expectedVisibility, $filesystem->visibility('to.txt'));
}

public static function fileMoveOrCopyScenarios(): iterable
{
yield 'retain visibility, write default, default private' => [
['retain_visibility' => true, 'visibility' => 'private'],
[],
null,
'private'
];
yield 'retain visibility, write default, default public' => [
['retain_visibility' => true, 'visibility' => 'public'],
[],
null,
'public'
];
yield 'retain visibility, write public, default private' => [
['retain_visibility' => true, 'visibility' => 'private'],
[],
'public',
'public'
];
yield 'retain visibility, write private, default public' => [
['retain_visibility' => true, 'visibility' => 'public'],
[],
'private',
'private'
];

yield 'retain visibility, write default, default private, execute public' => [
['retain_visibility' => true, 'visibility' => 'private'],
['visibility' => 'public'],
null,
'public'
];
yield 'retain visibility, write default, default public, execute private' => [
['retain_visibility' => true, 'visibility' => 'public'],
['visibility' => 'private'],
null,
'private'
];
yield 'retain visibility, write public, default private, execute private' => [
['retain_visibility' => true, 'visibility' => 'private'],
['visibility' => 'private'],
'public',
'private'
];
yield 'retain visibility, write private, default public, execute public' => [
['retain_visibility' => true, 'visibility' => 'public'],
['visibility' => 'public'],
'private',
'public'
];

yield 'do not retain visibility, write default, default private' => [
['retain_visibility' => false, 'visibility' => 'private'],
[],
null,
'private'
];
yield 'do not retain visibility, write default, default public' => [
['retain_visibility' => false, 'visibility' => 'public'],
[],
null,
'public'
];
yield 'do not retain visibility, write public, default private' => [
['retain_visibility' => false, 'visibility' => 'private'],
[],
'public',
'private'
];
yield 'do not retain visibility, write private, default public' => [
['retain_visibility' => false, 'visibility' => 'public'],
[],
'private',
'public'
];

yield 'do not retain visibility, write default, default private, execute public' => [
['retain_visibility' => false, 'visibility' => 'private'],
['visibility' => 'public'],
null,
'public'
];
yield 'do not retain visibility, write default, default public, execute private' => [
['retain_visibility' => false, 'visibility' => 'public'],
['visibility' => 'private'],
null,
'private'
];
yield 'do not retain visibility, write public, default private, execute public' => [
['retain_visibility' => false, 'visibility' => 'private'],
['visibility' => 'public'],
'public',
'public'
];
yield 'do not retain visibility, write private, default public, execute private' => [
['retain_visibility' => false, 'visibility' => 'public'],
['visibility' => 'private'],
'private',
'private'
];
}
}
9 changes: 8 additions & 1 deletion src/InMemory/InMemoryFilesystemAdapter.php
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,10 @@ public function move(string $source, string $destination, Config $config): void

$this->files[$destinationPath] = $this->files[$sourcePath];
unset($this->files[$sourcePath]);

if ($visibility = $config->get(Config::OPTION_VISIBILITY)) {
$this->setVisibility($destination, $visibility);
}
}

public function copy(string $source, string $destination, Config $config): void
Expand All @@ -242,8 +246,11 @@ public function copy(string $source, string $destination, Config $config): void
}

$lastModified = $config->get('timestamp', time());

$this->files[$destination] = $this->files[$source]->withLastModified($lastModified);

if ($visibility = $config->get(Config::OPTION_VISIBILITY)) {
$this->setVisibility($destination, $visibility);
}
}

private function preparePath(string $path): string
Expand Down

0 comments on commit 6155cb2

Please sign in to comment.