fix(storage): validate S3 connection with current form values (#11297)

This commit is contained in:
Andras Bacsai
2026-08-15 18:25:28 +02:00
committed by GitHub
2 changed files with 98 additions and 5 deletions
+24 -5
View File
@@ -122,20 +122,39 @@ class Form extends Component
public function testConnection()
{
$testedStorage = null;
try {
$this->authorize('validateConnection', $this->storage);
$testedStorage = new S3Storage;
$testedStorage->uuid = $this->storage->uuid;
$testedStorage->team_id = $this->storage->team_id;
$testedStorage->unusable_email_sent = $this->storage->unusable_email_sent;
$testedStorage->name = $this->name;
$testedStorage->description = $this->description;
$testedStorage->endpoint = $this->endpoint;
$testedStorage->bucket = $this->bucket;
$testedStorage->region = $this->region;
$testedStorage->key = $this->key;
$testedStorage->secret = $this->secret;
$this->storage->testConnection(shouldSave: true);
$testedStorage->testConnection();
// Update component property to reflect the new validation status
$this->isUsable = $this->storage->is_usable;
$this->isUsable = $testedStorage->is_usable;
$this->storage->is_usable = $testedStorage->is_usable;
$this->storage->unusable_email_sent = $testedStorage->unusable_email_sent;
$this->storage->save();
$this->dispatch('storage-status-changed', isUsable: $this->isUsable);
return $this->dispatch('success', 'Connection is working.', 'Tested with "ListObjectsV2" action.');
} catch (\Throwable $e) {
// Refresh model and sync to get the latest state
$this->storage->refresh();
$this->isUsable = $this->storage->is_usable;
if ($testedStorage) {
$this->isUsable = $testedStorage->is_usable;
$this->storage->is_usable = $testedStorage->is_usable;
$this->storage->unusable_email_sent = $testedStorage->unusable_email_sent;
$this->storage->save();
}
$this->dispatch('storage-status-changed', isUsable: $this->isUsable);
$this->dispatch('error', 'Failed to test connection.', $e->getMessage());
+74
View File
@@ -0,0 +1,74 @@
<?php
use App\Livewire\Storage\Form;
use App\Models\S3Storage;
use Illuminate\Support\Facades\Storage;
use Tests\TestCase;
uses(TestCase::class);
it('tests the S3 connection with the values currently entered in the form', function () {
if (! defined('CURLOPT_RESOLVE')) {
define('CURLOPT_RESOLVE', 10203);
}
$disk = Mockery::mock();
$disk->expects('files')->once()->andReturn([]);
$testedConfig = null;
Storage::expects('build')
->once()
->with(Mockery::on(function (array $config) use (&$testedConfig) {
$testedConfig = $config;
return true;
}))
->andReturn($disk);
$storage = new class extends S3Storage
{
public function save(array $options = []): bool
{
return true;
}
};
$storage->setRawAttributes([
'name' => 'Saved storage',
'description' => 'Saved description',
'endpoint' => 'https://nyc3.digitaloceanspaces.com',
'bucket' => 'old-bucket',
'region' => 'us-east-1',
'key' => null,
'secret' => null,
'is_usable' => false,
'unusable_email_sent' => true,
]);
$form = new class extends Form
{
public function authorize($ability, $arguments = []): void {}
public function dispatch($event, ...$params): void {}
};
$form->storage = $storage;
$form->name = 'Unsaved storage';
$form->description = 'Unsaved description';
$form->endpoint = 'https://s3.amazonaws.com';
$form->bucket = 'new-bucket';
$form->region = 'eu-central-1';
$form->key = 'new-key';
$form->secret = 'new-secret';
$form->isUsable = false;
$form->testConnection();
expect($form->endpoint)->toBe('https://s3.amazonaws.com')
->and($storage->endpoint)->toBe('https://nyc3.digitaloceanspaces.com')
->and($testedConfig)->toMatchArray([
'endpoint' => 'https://s3.amazonaws.com',
'bucket' => 'new-bucket',
'region' => 'eu-central-1',
'key' => 'new-key',
'secret' => 'new-secret',
])
->and($form->isUsable)->toBeTrue();
});