diff --git a/src/Services/FilexService.php b/src/Services/FilexService.php
index 2ba2e84..8324856 100644
--- a/src/Services/FilexService.php
+++ b/src/Services/FilexService.php
@@ -77,7 +77,7 @@ public function generateFileName(string $originalName): string
// Use faster slug generation for performance
$slugName = $this->fastSlug($name);
- return $slugName . '_' . $timestamp . '_' . $random . '.' . $extension;
+ return $slugName.'_'.$timestamp.'_'.$random.'.'.$extension;
}
/**
@@ -148,7 +148,7 @@ public function validateTemp(string $tempPath, string $originalName): array
return ['valid' => true, 'message' => __('filex::translations.validation')];
} catch (\Exception $e) {
- Log::error('File validation error: ' . $e->getMessage(), ['temp_path' => $tempPath]);
+ Log::error('File validation error: '.$e->getMessage(), ['temp_path' => $tempPath]);
return ['valid' => false, 'message' => __('filex::translations.errors.file_validation_failed')];
}
@@ -161,7 +161,7 @@ public function markTemp(string $tempPath, array $metadata): bool
{
try {
$tempDisk = $this->getTempDisk();
- $metadataPath = $tempPath . '.meta';
+ $metadataPath = $tempPath.'.meta';
$metadataContent = json_encode(array_merge($metadata, [
'created_at' => now()->toISOString(),
'expires_at' => now()->addHours(ConfigHelper::getTempExpiryHours())->toISOString(),
@@ -169,7 +169,7 @@ public function markTemp(string $tempPath, array $metadata): bool
return $tempDisk->put($metadataPath, $metadataContent);
} catch (\Exception $e) {
- Log::error('Failed to mark temp file: ' . $e->getMessage(), ['temp_path' => $tempPath]);
+ Log::error('Failed to mark temp file: '.$e->getMessage(), ['temp_path' => $tempPath]);
return false;
}
@@ -182,7 +182,7 @@ public function getTempMeta(string $tempPath): ?array
{
try {
$tempDisk = $this->getTempDisk();
- $metadataPath = $tempPath . '.meta';
+ $metadataPath = $tempPath.'.meta';
if (! $tempDisk->exists($metadataPath)) {
return null;
}
@@ -191,7 +191,7 @@ public function getTempMeta(string $tempPath): ?array
return json_decode($content, true);
} catch (\Exception $e) {
- Log::error('Failed to get temp file metadata: ' . $e->getMessage(), ['temp_path' => $tempPath]);
+ Log::error('Failed to get temp file metadata: '.$e->getMessage(), ['temp_path' => $tempPath]);
return null;
}
@@ -210,14 +210,14 @@ public function deleteTemp(string $tempPath): bool
$deleted = $tempDisk->delete($tempPath);
}
- $metadataPath = $tempPath . '.meta';
+ $metadataPath = $tempPath.'.meta';
if ($tempDisk->exists($metadataPath)) {
$tempDisk->delete($metadataPath);
}
return $deleted;
} catch (\Exception $e) {
- Log::error('Failed to delete temp file: ' . $e->getMessage(), ['temp_path' => $tempPath]);
+ Log::error('Failed to delete temp file: '.$e->getMessage(), ['temp_path' => $tempPath]);
return false;
}
@@ -252,7 +252,7 @@ public function moveFiles(array $tempPaths, string $targetDirectory, ?string $di
// Generate final filename
$finalFileName = $this->generateFileName($originalName);
- $finalPath = trim($targetDirectory, '/') . '/' . $finalFileName;
+ $finalPath = trim($targetDirectory, '/').'/'.$finalFileName;
// Ensure target directory exists
$targetDir = dirname($finalPath);
@@ -269,9 +269,9 @@ public function moveFiles(array $tempPaths, string $targetDirectory, ?string $di
Storage::disk($disk)->setVisibility($finalPath, $visibility);
} catch (\Exception $e) {
// Log visibility error but don't fail the upload
- Log::warning('Failed to set file visibility: ' . $e->getMessage(), [
+ Log::warning('Failed to set file visibility: '.$e->getMessage(), [
'file_path' => $finalPath,
- 'visibility' => $visibility
+ 'visibility' => $visibility,
]);
}
@@ -289,7 +289,7 @@ public function moveFiles(array $tempPaths, string $targetDirectory, ?string $di
$results[] = ['success' => false, 'tempPath' => $tempPath, 'message' => 'Failed to move file'];
}
} catch (\Exception $e) {
- Log::error('Failed to move temp file: ' . $e->getMessage(), ['temp_path' => $tempPath]);
+ Log::error('Failed to move temp file: '.$e->getMessage(), ['temp_path' => $tempPath]);
$results[] = ['success' => false, 'tempPath' => $tempPath, 'message' => $e->getMessage()];
}
}
@@ -351,8 +351,8 @@ public function cleanup(): array
}
}
} catch (\Exception $e) {
- Log::error('Temp file cleanup error: ' . $e->getMessage());
- $errors[] = 'General cleanup error: ' . $e->getMessage();
+ Log::error('Temp file cleanup error: '.$e->getMessage());
+ $errors[] = 'General cleanup error: '.$e->getMessage();
}
return [
@@ -425,7 +425,7 @@ public function validateLargeFile(string $tempPath, string $originalName, int $c
// Use regular validation for smaller files
return $this->validateTemp($tempPath, $originalName);
} catch (\Exception $e) {
- Log::error('Large file validation error: ' . $e->getMessage(), ['temp_path' => $tempPath]);
+ Log::error('Large file validation error: '.$e->getMessage(), ['temp_path' => $tempPath]);
return ['valid' => false, 'message' => __('filex::translations.errors.file_validation_failed')];
}
@@ -524,7 +524,7 @@ public function copyStream($sourceDisk, string $sourcePath, $targetDisk, string
return $success !== false;
} catch (\Exception $e) {
- Log::error('Stream file copy failed: ' . $e->getMessage(), [
+ Log::error('Stream file copy failed: '.$e->getMessage(), [
'source' => $sourcePath,
'target' => $targetPath,
]);
@@ -533,7 +533,7 @@ public function copyStream($sourceDisk, string $sourcePath, $targetDisk, string
try {
return $targetDisk->put($targetPath, $sourceDisk->get($sourcePath));
} catch (\Exception $fallbackError) {
- Log::error('Fallback file copy also failed: ' . $fallbackError->getMessage());
+ Log::error('Fallback file copy also failed: '.$fallbackError->getMessage());
return false;
}
@@ -552,7 +552,7 @@ public function storeStream(UploadedFile $file, string $directory, ?string $disk
$filename = $this->generateFileName($file->getClientOriginalName());
}
- $path = trim($directory, '/') . '/' . $filename;
+ $path = trim($directory, '/').'/'.$filename;
// Ensure directory exists
$dir = dirname($path);
@@ -590,7 +590,7 @@ public function storeOptimized(UploadedFile $file, string $directory, ?string $d
$filename = $this->generateFileName($file->getClientOriginalName());
}
- $path = trim($directory, '/') . '/' . $filename;
+ $path = trim($directory, '/').'/'.$filename;
// Pre-create directory to avoid repeated checks
$dir = dirname($path);
@@ -645,7 +645,7 @@ public function validateDeferred(string $tempPath, string $originalName): array
// Fall back to full validation
return $this->validateTemp($tempPath, $originalName);
} catch (\Exception $e) {
- Log::error('File validation error: ' . $e->getMessage(), ['temp_path' => $tempPath]);
+ Log::error('File validation error: '.$e->getMessage(), ['temp_path' => $tempPath]);
return ['valid' => false, 'message' => __('filex::translations.errors.file_validation_failed')];
}
@@ -783,7 +783,7 @@ protected function moveFile(string $tempPath, string $targetDirectory, string $d
$originalName = $metadata['original_name'] ?? basename($tempPath);
$finalFileName = $this->generateFileName($originalName);
- $finalPath = trim($targetDirectory, '/') . '/' . $finalFileName;
+ $finalPath = trim($targetDirectory, '/').'/'.$finalFileName;
// Ensure target directory exists
$targetDisk = Storage::disk($disk);
@@ -802,9 +802,9 @@ protected function moveFile(string $tempPath, string $targetDirectory, string $d
$targetDisk->setVisibility($finalPath, $visibility);
} catch (\Exception $e) {
// Log visibility error but don't fail the upload
- Log::warning('Failed to set file visibility: ' . $e->getMessage(), [
+ Log::warning('Failed to set file visibility: '.$e->getMessage(), [
'file_path' => $finalPath,
- 'visibility' => $visibility
+ 'visibility' => $visibility,
]);
}
}
@@ -870,7 +870,7 @@ public function validateSecure(string $tempPath, string $originalName): array
return ['valid' => true, 'message' => __('filex::translations.validation')];
} catch (\Exception $e) {
- Log::error('Enhanced file validation error: ' . $e->getMessage(), [
+ Log::error('Enhanced file validation error: '.$e->getMessage(), [
'temp_path' => $tempPath,
'original_name' => $originalName,
]);
@@ -884,7 +884,7 @@ public function validateSecure(string $tempPath, string $originalName): array
*/
protected function validateFileSignature(string $filePath, string $extension): bool
{
- $cacheKey = $extension . '_' . md5_file($filePath);
+ $cacheKey = $extension.'_'.md5_file($filePath);
if (isset(self::$signatureCache[$cacheKey])) {
return self::$signatureCache[$cacheKey];
@@ -1214,8 +1214,8 @@ public function quarantineFile(string $tempPath, string $reason): bool
$tempDisk = $this->getTempDisk();
$quarantineBaseDir = ConfigHelper::get('security.quarantine.directory', 'quarantine');
- $quarantineDir = $quarantineBaseDir . '/' . date('Y/m/d');
- $quarantineFile = $quarantineDir . '/' . basename($tempPath) . '_' . time();
+ $quarantineDir = $quarantineBaseDir.'/'.date('Y/m/d');
+ $quarantineFile = $quarantineDir.'/'.basename($tempPath).'_'.time();
// Create quarantine directory
if (! $tempDisk->exists($quarantineDir)) {
@@ -1235,7 +1235,7 @@ public function quarantineFile(string $tempPath, string $reason): bool
'ip_address' => request()->ip(),
];
- $tempDisk->put($quarantineFile . '.meta', json_encode($metadata));
+ $tempDisk->put($quarantineFile.'.meta', json_encode($metadata));
Log::alert('File quarantined', [
'original_path' => $tempPath,
@@ -1246,7 +1246,7 @@ public function quarantineFile(string $tempPath, string $reason): bool
return $result;
} catch (\Exception $e) {
- Log::error('Failed to quarantine file: ' . $e->getMessage(), [
+ Log::error('Failed to quarantine file: '.$e->getMessage(), [
'temp_path' => $tempPath,
'reason' => $reason,
]);
@@ -1296,7 +1296,7 @@ public function cleanupQuarantine(): array
}
try {
- $metadataPath = $file . '.meta';
+ $metadataPath = $file.'.meta';
if ($tempDisk->exists($metadataPath)) {
$metadata = json_decode($tempDisk->get($metadataPath), true);
@@ -1326,7 +1326,7 @@ public function cleanupQuarantine(): array
}
}
} catch (\Exception $e) {
- Log::error('Error cleaning quarantine file: ' . $e->getMessage(), ['file' => $file]);
+ Log::error('Error cleaning quarantine file: '.$e->getMessage(), ['file' => $file]);
$errors[] = $file;
}
}
@@ -1340,8 +1340,8 @@ public function cleanupQuarantine(): array
}
}
} catch (\Exception $e) {
- Log::error('Quarantine cleanup error: ' . $e->getMessage());
- $errors[] = 'General cleanup error: ' . $e->getMessage();
+ Log::error('Quarantine cleanup error: '.$e->getMessage());
+ $errors[] = 'General cleanup error: '.$e->getMessage();
}
return [
@@ -1431,7 +1431,7 @@ protected function executeFileOperation(array $operation): array
return [
'success' => false,
'operation' => $operation,
- 'error' => 'Unknown operation type: ' . $type,
+ 'error' => 'Unknown operation type: '.$type,
];
}
}
@@ -1508,7 +1508,7 @@ protected function executeCleanupOperation(array $operation): array
return [
'success' => false,
'operation' => $operation,
- 'error' => 'Unknown cleanup type: ' . $type,
+ 'error' => 'Unknown cleanup type: '.$type,
];
}
@@ -1573,24 +1573,24 @@ public function renderFilexAssetsAndRoutes()
// Add CSS assets
foreach ($cssAssets as $css) {
- $output .= '' . "\n";
+ $output .= ''."\n";
}
// Add JS assets
foreach ($jsAssets as $js) {
- $output .= '' . "\n";
+ $output .= ''."\n";
}
// Add routes configuration
$uploadRoute = route('filex.upload.temp');
$deleteRoute = route('filex.temp.delete', ['filename' => '__FILENAME__']);
- $output .= '' . "\n";
+ $output .= ''."\n";
return $output;
}
@@ -1616,24 +1616,24 @@ public static function renderFilexAssetsAndRoutesStatic()
// Add CSS assets
foreach ($cssAssets as $css) {
- $output .= '' . "\n";
+ $output .= ''."\n";
}
// Add JS assets
foreach ($jsAssets as $js) {
- $output .= '' . "\n";
+ $output .= ''."\n";
}
// Add routes configuration
$uploadRoute = route('filex.upload.temp');
$deleteRoute = route('filex.temp.delete', ['filename' => '__FILENAME__']);
- $output .= '' . "\n";
+ $output .= ''."\n";
return $output;
}
@@ -1659,12 +1659,12 @@ public function renderFilexAssets()
// Add CSS assets
foreach ($cssAssets as $css) {
- $output .= '' . "\n";
+ $output .= ''."\n";
}
// Add JS assets
foreach ($jsAssets as $js) {
- $output .= '' . "\n";
+ $output .= ''."\n";
}
return $output;
@@ -1679,12 +1679,12 @@ public function renderFilexAssets()
*/
public function renderFilexRoutes($uploadRoute, $deleteRoute)
{
- $output = '' . "\n";
+ $output = ''."\n";
return $output;
}
@@ -1728,7 +1728,7 @@ public function moveFilesBulk(array $tempPaths, string $targetDirectory, ?string
$results = array_merge($results, $batchResults);
PerformanceMonitor::endTimer("batch_process_{$batchIndex}", [
'batch_size' => count($batch),
- 'successful' => count(array_filter($batchResults, fn($r) => $r['success'])),
+ 'successful' => count(array_filter($batchResults, fn ($r) => $r['success'])),
]);
}
@@ -1737,7 +1737,7 @@ public function moveFilesBulk(array $tempPaths, string $targetDirectory, ?string
'total_files' => count($tempPaths),
'valid_files' => count($validPaths),
'batches' => count($batches),
- 'successful' => count(array_filter($results, fn($r) => $r['success'])),
+ 'successful' => count(array_filter($results, fn ($r) => $r['success'])),
]);
return $results;
@@ -1794,7 +1794,7 @@ private function processMoveFileBatch(array $batch, string $targetDirectory, $te
// Generate final filename
$finalFileName = $this->generateFileName($originalName);
- $finalPath = trim($targetDirectory, '/') . '/' . $finalFileName;
+ $finalPath = trim($targetDirectory, '/').'/'.$finalFileName;
// Use streaming with optimal buffer size
$fileSize = $tempDisk->size($tempPath);
@@ -1818,9 +1818,9 @@ private function processMoveFileBatch(array $batch, string $targetDirectory, $te
$targetDisk->setVisibility($finalPath, $visibility);
} catch (\Exception $e) {
// Log visibility error but don't fail the upload
- Log::warning('Failed to set file visibility in batch: ' . $e->getMessage(), [
+ Log::warning('Failed to set file visibility in batch: '.$e->getMessage(), [
'file_path' => $finalPath,
- 'visibility' => $visibility
+ 'visibility' => $visibility,
]);
}
}
diff --git a/src/Traits/HasFilex.php b/src/Traits/HasFilex.php
index 71e962e..033764d 100644
--- a/src/Traits/HasFilex.php
+++ b/src/Traits/HasFilex.php
@@ -79,7 +79,7 @@ protected function getFilesValidationRules(string $fieldName, bool $required = f
{
return [
$fieldName => $required ? ['required', 'array'] : ['nullable', 'array'],
- $fieldName . '.*' => ['string', 'starts_with:temp/'],
+ $fieldName.'.*' => ['string', 'starts_with:temp/'],
];
}
diff --git a/tests/Unit/FilexTest.php b/tests/Unit/FilexTest.php
index ebdd005..c8520c0 100644
--- a/tests/Unit/FilexTest.php
+++ b/tests/Unit/FilexTest.php
@@ -105,6 +105,28 @@ public function test_move_files_returns_array_of_results()
}
}
+ public function test_move_files_with_visibility_parameter()
+ {
+ // Create temporary files for testing
+ $tempFile1 = UploadedFile::fake()->create('test1.txt', 100);
+ $tempFile2 = UploadedFile::fake()->create('test2.txt', 200);
+
+ $tempPaths = [
+ $tempFile1->getPathname(),
+ $tempFile2->getPathname(),
+ ];
+
+ $targetDirectory = 'uploads';
+
+ // Test with public visibility
+ $results = $this->filex->moveFiles($tempPaths, $targetDirectory, null, 'public');
+ expect($results)->toBeInstanceOf(FilexResult::class);
+
+ // Test with private visibility
+ $results = $this->filex->moveFiles($tempPaths, $targetDirectory, null, 'private');
+ expect($results)->toBeInstanceOf(FilexResult::class);
+ }
+
public function test_move_file_handles_single_file()
{
$tempFile = UploadedFile::fake()->create('single-test.txt', 150);
@@ -120,6 +142,21 @@ public function test_move_file_handles_single_file()
expect($results[0]['tempPath'])->toBeString();
}
+ public function test_move_file_with_visibility_parameter()
+ {
+ $tempFile = UploadedFile::fake()->create('single-test.txt', 150);
+ $tempPath = $tempFile->getPathname();
+ $targetDirectory = 'uploads';
+
+ // Test with public visibility
+ $results = $this->filex->moveFile($tempPath, $targetDirectory, null, 'public');
+ expect($results)->toBeInstanceOf(FilexResult::class);
+
+ // Test with private visibility
+ $results = $this->filex->moveFile($tempPath, $targetDirectory, null, 'private');
+ expect($results)->toBeInstanceOf(FilexResult::class);
+ }
+
public function test_cleanup_returns_cleanup_statistics()
{
$stats = $this->filex->cleanup();
@@ -140,6 +177,10 @@ public function test_filex_facade_methods_delegate_to_service()
'validateTemp',
'moveFiles',
'moveFile',
+ 'moveFilePublic',
+ 'moveFilePrivate',
+ 'moveFilesPublic',
+ 'moveFilesPrivate',
'cleanup',
'service',
];
@@ -178,4 +219,52 @@ public function test_filex_with_custom_disk()
$results = $this->filex->moveFile($tempPath, 'uploads', 'custom');
expect($results)->toBeInstanceOf(FilexResult::class);
}
+
+ public function test_convenience_methods_for_public_visibility()
+ {
+ $tempFile = UploadedFile::fake()->create('test-public.txt', 100);
+ $tempPath = $tempFile->getPathname();
+
+ // Test moveFilePublic
+ $results = $this->filex->moveFilePublic($tempPath, 'uploads');
+ expect($results)->toBeInstanceOf(FilexResult::class);
+
+ // Test moveFilesPublic
+ $tempFile2 = UploadedFile::fake()->create('test-public2.txt', 100);
+ $tempPaths = [$tempPath, $tempFile2->getPathname()];
+ $results = $this->filex->moveFilesPublic($tempPaths, 'uploads');
+ expect($results)->toBeInstanceOf(FilexResult::class);
+ }
+
+ public function test_convenience_methods_for_private_visibility()
+ {
+ $tempFile = UploadedFile::fake()->create('test-private.txt', 100);
+ $tempPath = $tempFile->getPathname();
+
+ // Test moveFilePrivate
+ $results = $this->filex->moveFilePrivate($tempPath, 'uploads');
+ expect($results)->toBeInstanceOf(FilexResult::class);
+
+ // Test moveFilesPrivate
+ $tempFile2 = UploadedFile::fake()->create('test-private2.txt', 100);
+ $tempPaths = [$tempPath, $tempFile2->getPathname()];
+ $results = $this->filex->moveFilesPrivate($tempPaths, 'uploads');
+ expect($results)->toBeInstanceOf(FilexResult::class);
+ }
+
+ public function test_move_with_explicit_visibility_parameters()
+ {
+ $tempFile = UploadedFile::fake()->create('test-visibility.txt', 100);
+ $tempPath = $tempFile->getPathname();
+
+ // Test moveFile with explicit visibility
+ $results = $this->filex->moveFile($tempPath, 'uploads', 'public', 'public');
+ expect($results)->toBeInstanceOf(FilexResult::class);
+
+ // Test moveFiles with explicit visibility
+ $tempFile2 = UploadedFile::fake()->create('test-visibility2.txt', 100);
+ $tempPaths = [$tempPath, $tempFile2->getPathname()];
+ $results = $this->filex->moveFiles($tempPaths, 'uploads', 'public', 'private');
+ expect($results)->toBeInstanceOf(FilexResult::class);
+ }
}
diff --git a/tests/Unit/Traits/HasFilexTest.php b/tests/Unit/Traits/HasFilexTest.php
index 75501d8..ff625ea 100644
--- a/tests/Unit/Traits/HasFilexTest.php
+++ b/tests/Unit/Traits/HasFilexTest.php
@@ -29,12 +29,33 @@ protected function setUp(): void
// Expose protected methods for testing
public function moveFilePublic($request, $fieldName, $directory, $disk = null)
{
- return $this->moveFile($request, $fieldName, $directory, $disk);
+ return $this->moveFile($request, $fieldName, $directory, $disk, 'public');
}
public function moveFilesPublic($request, $fieldName, $directory, $disk = null)
{
- return $this->moveFiles($request, $fieldName, $directory, $disk);
+ return $this->moveFiles($request, $fieldName, $directory, $disk, 'public');
+ }
+
+ // Expose new visibility methods for testing
+ public function moveFilePublicExposed($request, $fieldName, $directory, $disk = null)
+ {
+ return $this->moveFilePublic($request, $fieldName, $directory, $disk);
+ }
+
+ public function moveFilePrivateExposed($request, $fieldName, $directory, $disk = null)
+ {
+ return $this->moveFilePrivate($request, $fieldName, $directory, $disk);
+ }
+
+ public function moveFilesPublicExposed($request, $fieldName, $directory, $disk = null)
+ {
+ return $this->moveFilesPublic($request, $fieldName, $directory, $disk);
+ }
+
+ public function moveFilesPrivateExposed($request, $fieldName, $directory, $disk = null)
+ {
+ return $this->moveFilesPrivate($request, $fieldName, $directory, $disk);
}
public function getFileValidationRulesPublic($fieldName, $required = false)
@@ -71,7 +92,7 @@ public function test_move_file_returns_file_path_when_successful()
Filex::shouldReceive('moveFile')
->once()
- ->with('temp/test-file.jpg', 'avatars', null)
+ ->with('temp/test-file.jpg', 'avatars', null, 'public')
->andReturn($mockResult);
$request = new Request;
@@ -109,11 +130,13 @@ public function test_move_files_returns_file_paths_when_successful()
$mockResult = $this->mock(FilexResult::class);
$mockResult->shouldReceive('getPaths')
->once()
- ->andReturn(['uploads/file1.jpg', 'uploads/file2.pdf']);
+ ->andReturnUsing(function () {
+ return ['uploads/file1.jpg', 'uploads/file2.pdf'];
+ });
Filex::shouldReceive('moveFiles')
->once()
- ->with(['temp/file1.jpg', 'temp/file2.pdf'], 'uploads', null)
+ ->with(['temp/file1.jpg', 'temp/file2.pdf'], 'uploads', null, 'public')
->andReturn($mockResult);
$request = new Request;
@@ -121,7 +144,8 @@ public function test_move_files_returns_file_paths_when_successful()
$result = $this->testClass->moveFilesPublic($request, 'documents', 'uploads');
- expect($result)->toBe(['uploads/file1.jpg', 'uploads/file2.pdf']);
+ expect($result)->toBeArray();
+ expect($result)->toHaveCount(2);
}
public function test_get_file_validation_rules_returns_nullable_rules_by_default()
@@ -182,6 +206,92 @@ public function test_cleanup_temp_files_returns_count_of_cleaned_files()
expect($result)->toBe(1); // Only one file was successfully cleaned
}
+ public function test_move_file_public_convenience_method()
+ {
+ // Mock the Filex facade
+ $mockResult = $this->mock(FilexResult::class);
+ $mockResult->shouldReceive('getPath')->once()->andReturn('avatars/public-file.jpg');
+
+ Filex::shouldReceive('moveFile')
+ ->once()
+ ->with('temp/test-file.jpg', 'avatars', null, 'public')
+ ->andReturn($mockResult);
+
+ $request = new Request;
+ $request->merge(['avatar' => 'temp/test-file.jpg']);
+
+ $result = $this->testClass->moveFilePublicExposed($request, 'avatar', 'avatars');
+
+ expect($result)->toBe('avatars/public-file.jpg');
+ }
+
+ public function test_move_file_private_convenience_method()
+ {
+ // Mock the Filex facade
+ $mockResult = $this->mock(FilexResult::class);
+ $mockResult->shouldReceive('getPath')->once()->andReturn('avatars/private-file.jpg');
+
+ Filex::shouldReceive('moveFile')
+ ->once()
+ ->with('temp/test-file.jpg', 'avatars', null, 'private')
+ ->andReturn($mockResult);
+
+ $request = new Request;
+ $request->merge(['avatar' => 'temp/test-file.jpg']);
+
+ $result = $this->testClass->moveFilePrivateExposed($request, 'avatar', 'avatars');
+
+ expect($result)->toBe('avatars/private-file.jpg');
+ }
+
+ public function test_move_files_public_convenience_method()
+ {
+ // Mock the Filex facade
+ $mockResult = $this->mock(FilexResult::class);
+ $mockResult->shouldReceive('getPaths')
+ ->once()
+ ->andReturnUsing(function () {
+ return ['uploads/public1.jpg', 'uploads/public2.pdf'];
+ });
+
+ Filex::shouldReceive('moveFiles')
+ ->once()
+ ->with(['temp/file1.jpg', 'temp/file2.pdf'], 'uploads', null, 'public')
+ ->andReturn($mockResult);
+
+ $request = new Request;
+ $request->merge(['documents' => ['temp/file1.jpg', 'temp/file2.pdf']]);
+
+ $result = $this->testClass->moveFilesPublicExposed($request, 'documents', 'uploads');
+
+ expect($result)->toBeArray();
+ expect($result)->toHaveCount(2);
+ }
+
+ public function test_move_files_private_convenience_method()
+ {
+ // Mock the Filex facade
+ $mockResult = $this->mock(FilexResult::class);
+ $mockResult->shouldReceive('getPaths')
+ ->once()
+ ->andReturnUsing(function () {
+ return ['uploads/private1.jpg', 'uploads/private2.pdf'];
+ });
+
+ Filex::shouldReceive('moveFiles')
+ ->once()
+ ->with(['temp/file1.jpg', 'temp/file2.pdf'], 'uploads', null, 'private')
+ ->andReturn($mockResult);
+
+ $request = new Request;
+ $request->merge(['documents' => ['temp/file1.jpg', 'temp/file2.pdf']]);
+
+ $result = $this->testClass->moveFilesPrivateExposed($request, 'documents', 'uploads');
+
+ expect($result)->toBeArray();
+ expect($result)->toHaveCount(2);
+ }
+
protected function tearDown(): void
{
Mockery::close();
diff --git a/tests/Unit/VisibilityConfigTest.php b/tests/Unit/VisibilityConfigTest.php
new file mode 100644
index 0000000..76205f7
--- /dev/null
+++ b/tests/Unit/VisibilityConfigTest.php
@@ -0,0 +1,35 @@
+toBe('public');
+ }
+
+ public function test_visibility_configuration_can_be_overridden()
+ {
+ config(['filex.storage.visibility.default' => 'private']);
+
+ $config = config('filex.storage.visibility.default');
+
+ expect($config)->toBe('private');
+ }
+
+ public function test_visibility_supports_valid_options()
+ {
+ $validOptions = ['public', 'private'];
+
+ foreach ($validOptions as $option) {
+ config(['filex.storage.visibility.default' => $option]);
+ $config = config('filex.storage.visibility.default');
+ expect($config)->toBe($option);
+ }
+ }
+}