190 lines
5.6 KiB
PHP
190 lines
5.6 KiB
PHP
<?php
|
|
|
|
namespace Tests\Unit\Storage;
|
|
|
|
use App\Services\Storage\FileStorageException;
|
|
use App\Services\Storage\LocalStorageDriver;
|
|
use App\Services\Storage\S3StorageDriver;
|
|
use CodeIgniter\HTTP\DownloadResponse;
|
|
use Config\Storage;
|
|
use Tests\Support\Storage\StorageTestCase;
|
|
|
|
/**
|
|
* @internal
|
|
*/
|
|
final class StorageConfigTest extends StorageTestCase
|
|
{
|
|
public function testDefaultsToLocalDriverWhenEnvMissing(): void
|
|
{
|
|
$config = new Storage();
|
|
|
|
$this->assertSame('local', $config->driver);
|
|
}
|
|
|
|
public function testInvalidDriverFallsBackToLocal(): void
|
|
{
|
|
$previous = getenv('FILE_STORAGE_DRIVER');
|
|
putenv('FILE_STORAGE_DRIVER=invalid');
|
|
|
|
try {
|
|
$config = new Storage();
|
|
$this->assertSame('local', $config->driver);
|
|
} finally {
|
|
if ($previous === false) {
|
|
putenv('FILE_STORAGE_DRIVER');
|
|
} else {
|
|
putenv('FILE_STORAGE_DRIVER=' . $previous);
|
|
}
|
|
}
|
|
}
|
|
|
|
public function testRetainLocalParsesBooleanEnv(): void
|
|
{
|
|
$previous = getenv('RETAIN_LOCAL');
|
|
putenv('RETAIN_LOCAL=true');
|
|
|
|
try {
|
|
$config = new Storage();
|
|
$this->assertTrue($config->retainLocal);
|
|
} finally {
|
|
if ($previous === false) {
|
|
putenv('RETAIN_LOCAL');
|
|
} else {
|
|
putenv('RETAIN_LOCAL=' . $previous);
|
|
}
|
|
}
|
|
}
|
|
|
|
public function testS3DriverRequiresCredentials(): void
|
|
{
|
|
$config = new Storage();
|
|
$config->driver = 's3';
|
|
$config->s3Bucket = '';
|
|
$config->s3AccessKey = '';
|
|
$config->s3SecretKey = '';
|
|
|
|
$this->expectException(FileStorageException::class);
|
|
$this->expectExceptionMessage('S3 storage is not configured');
|
|
|
|
new S3StorageDriver($config);
|
|
}
|
|
|
|
public function testFileStorageServiceReportsDriverMode(): void
|
|
{
|
|
$this->assertFalse(storage()->isS3());
|
|
|
|
$this->storageConfig->driver = 's3';
|
|
$this->storageConfig->s3Bucket = 'test-bucket';
|
|
$this->storageConfig->s3AccessKey = 'key';
|
|
$this->storageConfig->s3SecretKey = 'secret';
|
|
|
|
\Config\Services::injectMock('fileStorage', new \App\Services\FileStorageService($this->storageConfig));
|
|
|
|
$this->assertTrue(storage()->isS3());
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @internal
|
|
*/
|
|
final class LocalStorageDriverTest extends StorageTestCase
|
|
{
|
|
private LocalStorageDriver $driver;
|
|
|
|
protected function setUp(): void
|
|
{
|
|
parent::setUp();
|
|
|
|
$this->driver = new LocalStorageDriver($this->storageConfig);
|
|
}
|
|
|
|
public function testUploadFromUploadedFileStoresUnderLocalRoot(): void
|
|
{
|
|
$file = $this->createUploadedFile('%PDF-1.4 policy', 'policy.pdf', 'application/pdf');
|
|
$key = 'uploads/policy/policy_pdf/test_policy.pdf';
|
|
|
|
$this->driver->upload($file, $key);
|
|
|
|
$this->assertFileExists($this->localFilePath($key));
|
|
$this->assertSame('%PDF-1.4 policy', file_get_contents($this->localFilePath($key)));
|
|
}
|
|
|
|
public function testUploadFromLocalPathCopiesFile(): void
|
|
{
|
|
$source = tempnam(sys_get_temp_dir(), 'src_');
|
|
file_put_contents($source, 'receipt bytes');
|
|
$key = 'uploads/policy/policy_payment_receipt/receipt.pdf';
|
|
|
|
$this->driver->upload($source, $key);
|
|
|
|
$this->assertFileExists($this->localFilePath($key));
|
|
$this->assertSame('receipt bytes', file_get_contents($this->localFilePath($key)));
|
|
}
|
|
|
|
public function testPutWriteRawContents(): void
|
|
{
|
|
$key = 'uploads/policy/policy_md/sample.md';
|
|
|
|
$this->driver->put($key, '# Markdown content');
|
|
|
|
$this->assertTrue($this->driver->exists($key));
|
|
$this->assertSame('# Markdown content', $this->driver->read($key));
|
|
}
|
|
|
|
public function testExistsReturnsFalseForMissingFile(): void
|
|
{
|
|
$this->assertFalse($this->driver->exists('uploads/policy/policy_pdf/missing.pdf'));
|
|
}
|
|
|
|
public function testDeleteRemovesFile(): void
|
|
{
|
|
$key = 'uploads/endorsement/original.pdf';
|
|
$this->driver->put($key, 'endorsement');
|
|
|
|
$this->assertTrue($this->driver->delete($key));
|
|
$this->assertFalse($this->driver->exists($key));
|
|
}
|
|
|
|
public function testDownloadToTempReturnsExistingLocalPath(): void
|
|
{
|
|
$key = 'uploads/policy/policy_pdf/read.pdf';
|
|
$this->driver->put($key, 'pdf-data');
|
|
|
|
$path = $this->driver->downloadToTemp($key);
|
|
|
|
$this->assertSame($this->localFilePath($key), $path);
|
|
}
|
|
|
|
public function testCopyDuplicatesFile(): void
|
|
{
|
|
$from = 'uploads/policy/policy_pdf/source.pdf';
|
|
$to = 'uploads/policy/policy_pdf/copy.pdf';
|
|
$this->driver->put($from, 'copy-me');
|
|
|
|
$this->assertTrue($this->driver->copy($from, $to));
|
|
$this->assertSame('copy-me', $this->driver->read($to));
|
|
}
|
|
|
|
public function testTemporaryUrlUsesBaseUrlForLocalDriver(): void
|
|
{
|
|
$key = 'uploads/policy/policy_pdf/url.pdf';
|
|
$this->driver->put($key, 'url');
|
|
|
|
$url = $this->driver->temporaryUrl($key);
|
|
|
|
$this->assertStringContainsString('uploads/policy/policy_pdf/url.pdf', $url);
|
|
}
|
|
|
|
public function testStreamDownloadReturnsResponseWithBody(): void
|
|
{
|
|
$key = 'uploads/endorsement/endorsement_pdf/completion.pdf';
|
|
$this->driver->put($key, 'completion pdf');
|
|
|
|
$response = $this->driver->streamDownload($key, 'completion.pdf');
|
|
|
|
$this->assertInstanceOf(DownloadResponse::class, $response);
|
|
$this->assertDownloadHeaders($response, 'attachment');
|
|
$this->assertSame(strlen('completion pdf'), $response->getContentLength());
|
|
}
|
|
}
|