diff --git a/app/Http/Controllers/App/WorkspaceController.php b/app/Http/Controllers/App/WorkspaceController.php index a8451a02..d9d394ff 100644 --- a/app/Http/Controllers/App/WorkspaceController.php +++ b/app/Http/Controllers/App/WorkspaceController.php @@ -21,12 +21,10 @@ use Illuminate\Http\RedirectResponse; use Illuminate\Http\Request; use Illuminate\Http\Resources\Json\AnonymousResourceCollection; -use Illuminate\Support\Facades\Log; use Inertia\Inertia; use Inertia\Response; use RuntimeException; use Symfony\Component\HttpFoundation\Response as SymfonyResponse; -use Throwable; class WorkspaceController extends Controller { @@ -105,15 +103,7 @@ public function store(StoreWorkspaceRequest $request, LogoAttacher $logoAttacher $workspace = CreateWorkspace::execute($user, $validated); if ($logoUrl = data_get($validated, 'logo_url')) { - try { - $logoAttacher->attach($workspace, $logoUrl); - } catch (Throwable $e) { - Log::warning('Logo attach failed during workspace creation', [ - 'workspace_id' => $workspace->id, - 'logo_url' => $logoUrl, - 'error' => $e->getMessage(), - ]); - } + $logoAttacher->attach($workspace, $logoUrl); } return redirect()->route('app.accounts') @@ -217,15 +207,7 @@ public function updateSettings(UpdateWorkspaceRequest $request, LogoAttacher $lo $workspace->update($validated); if ($logoUrl) { - try { - $logoAttacher->attach($workspace, $logoUrl); - } catch (Throwable $e) { - Log::warning('Logo attach failed during workspace update', [ - 'workspace_id' => $workspace->id, - 'logo_url' => $logoUrl, - 'error' => $e->getMessage(), - ]); - } + $logoAttacher->attach($workspace, $logoUrl); } return back()->with('flash.success', __('settings.flash.workspace_updated')); diff --git a/app/Services/Brand/LogoAttacher.php b/app/Services/Brand/LogoAttacher.php index a091c7b3..71ca030a 100644 --- a/app/Services/Brand/LogoAttacher.php +++ b/app/Services/Brand/LogoAttacher.php @@ -6,6 +6,7 @@ use App\Models\Workspace; use Illuminate\Support\Facades\Log; +use Throwable; class LogoAttacher { @@ -77,6 +78,10 @@ public function attach(Workspace $workspace, string $logoUrl): bool ); return true; + } catch (Throwable $e) { + Log::warning('Logo rejected — persistence error', ['url' => $logoUrl, 'error' => $e->getMessage()]); + + return false; } finally { if (file_exists($tempPath)) { @unlink($tempPath); diff --git a/tests/Unit/Services/Brand/LogoAttacherTest.php b/tests/Unit/Services/Brand/LogoAttacherTest.php new file mode 100644 index 00000000..d43191a7 --- /dev/null +++ b/tests/Unit/Services/Brand/LogoAttacherTest.php @@ -0,0 +1,53 @@ + Http::response($body, 200, [ + 'Content-Type' => $mime, + 'Content-Length' => (string) strlen($body), + ])]); +} + +test('attaches the downloaded logo and returns true', function () { + fakeLogo(); + + $workspace = mock(Workspace::class); + $workspace->shouldReceive('clearMediaCollection')->once(); + $workspace->shouldReceive('addMediaFromPath')->once(); + + expect(app(LogoAttacher::class)->attach($workspace, LOGO_URL))->toBeTrue(); +}); + +test('swallows a persistence failure and returns false', function () { + fakeLogo(); + + $workspace = mock(Workspace::class); + $workspace->shouldReceive('clearMediaCollection')->once()->andThrow(new RuntimeException('media store down')); + + expect(app(LogoAttacher::class)->attach($workspace, LOGO_URL))->toBeFalse(); +}); + +test('returns false when the fetch fails', function () { + Http::fake(['*' => Http::response('', 500)]); + + expect(app(LogoAttacher::class)->attach(mock(Workspace::class), LOGO_URL))->toBeFalse(); +}); + +test('rejects a disallowed mime type and returns false', function () { + fakeLogo('text/html', ''); + + $workspace = mock(Workspace::class); + $workspace->shouldNotReceive('addMediaFromPath'); + + expect(app(LogoAttacher::class)->attach($workspace, LOGO_URL))->toBeFalse(); +});