fix: serve public media on same-origin storage paths

Pest Browser hosts on 127.0.0.1:port while Storage::url used
http://localhost, so screenshots captured broken images. Use relative
/storage URLs for media and absolutize only OG tags via url().

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-07-29 08:55:24 -03:00
parent 2405160046
commit 0adaadd9ed
4 changed files with 44 additions and 6 deletions

View File

@@ -62,7 +62,7 @@ final readonly class PageMeta
: (filled($case->summary) ? (string) $case->summary : self::defaultDescription($settings)); : (filled($case->summary) ? (string) $case->summary : self::defaultDescription($settings));
$ogImageUrl = filled($case->cover_image_path) $ogImageUrl = filled($case->cover_image_path)
? Storage::disk('public')->url((string) $case->cover_image_path) ? url(Storage::disk('public')->url((string) $case->cover_image_path))
: self::defaultOgImageUrl($settings); : self::defaultOgImageUrl($settings);
$ogImageAlt = filled($case->cover_image_alt) $ogImageAlt = filled($case->cover_image_alt)
@@ -98,6 +98,6 @@ final readonly class PageMeta
return null; return null;
} }
return Storage::disk('public')->url((string) $settings->default_og_image_path); return url(Storage::disk('public')->url((string) $settings->default_og_image_path));
} }
} }

View File

@@ -41,7 +41,9 @@ return [
'public' => [ 'public' => [
'driver' => 'local', 'driver' => 'local',
'root' => storage_path('app/public'), 'root' => storage_path('app/public'),
'url' => rtrim(env('APP_URL', 'http://localhost'), '/').'/storage', // Same-origin path so Pest Browser / any host:port can load media.
// Absolute URLs for OG tags should be built with url(...).
'url' => '/storage',
'visibility' => 'public', 'visibility' => 'public',
'throw' => false, 'throw' => false,
'report' => false, 'report' => false,

View File

@@ -0,0 +1,36 @@
<?php
declare(strict_types=1);
use App\Models\SiteSetting;
use Database\Seeders\VisualContentSeeder;
use Illuminate\Support\Facades\Artisan;
use Illuminate\Support\Facades\Storage;
it('exposes public disk urls as same-origin storage paths', function (): void {
expect(Storage::disk('public')->url('visual/og/og-default.jpg'))
->toStartWith('/storage/')
->not->toContain('http://localhost');
});
it('links seeded visual fixtures into public storage', function (): void {
Artisan::call('storage:link', ['--force' => true]);
Artisan::call('db:seed', ['--class' => VisualContentSeeder::class, '--force' => true]);
$settings = SiteSetting::instance();
$path = (string) $settings->default_og_image_path;
expect($path)->not->toBeEmpty()
->and(is_file(public_path('storage/'.$path)))->toBeTrue()
->and(mime_content_type(public_path('storage/'.$path)))->toBe('image/jpeg');
});
it('renders home media with same-origin storage urls', function (): void {
Artisan::call('db:seed', ['--class' => VisualContentSeeder::class, '--force' => true]);
$html = $this->get('/')->assertOk()->getContent();
expect($html)
->toContain('src="/storage/visual/')
->not->toContain('src="http://localhost/storage/');
});

View File

@@ -33,7 +33,7 @@ class PageMetaTest extends TestCase
$this->assertSame('Assessoria premium.', $meta->description); $this->assertSame('Assessoria premium.', $meta->description);
$this->assertSame('https://amare.test/sobre', $meta->canonical); $this->assertSame('https://amare.test/sobre', $meta->canonical);
$this->assertSame('website', $meta->ogType); $this->assertSame('website', $meta->ogType);
$this->assertSame(Storage::disk('public')->url('og/default.jpg'), $meta->ogImageUrl); $this->assertSame(url(Storage::disk('public')->url('og/default.jpg')), $meta->ogImageUrl);
$this->assertSame('Marca Amare', $meta->ogImageAlt); $this->assertSame('Marca Amare', $meta->ogImageAlt);
} }
@@ -93,7 +93,7 @@ class PageMetaTest extends TestCase
$this->assertSame('Descrição SEO do casamento', $meta->description); $this->assertSame('Descrição SEO do casamento', $meta->description);
$this->assertSame('https://amare.test/portfolio/casamento-jardim', $meta->canonical); $this->assertSame('https://amare.test/portfolio/casamento-jardim', $meta->canonical);
$this->assertSame('article', $meta->ogType); $this->assertSame('article', $meta->ogType);
$this->assertSame(Storage::disk('public')->url('cases/cover.jpg'), $meta->ogImageUrl); $this->assertSame(url(Storage::disk('public')->url('cases/cover.jpg')), $meta->ogImageUrl);
$this->assertSame('Capa do casamento', $meta->ogImageAlt); $this->assertSame('Capa do casamento', $meta->ogImageAlt);
} }
@@ -125,7 +125,7 @@ class PageMetaTest extends TestCase
$this->assertSame('Casamento Praia', $meta->title); $this->assertSame('Casamento Praia', $meta->title);
$this->assertSame('Resumo praia', $meta->description); $this->assertSame('Resumo praia', $meta->description);
$this->assertSame(Storage::disk('public')->url('og/default.jpg'), $meta->ogImageUrl); $this->assertSame(url(Storage::disk('public')->url('og/default.jpg')), $meta->ogImageUrl);
$this->assertSame('Default alt', $meta->ogImageAlt); $this->assertSame('Default alt', $meta->ogImageAlt);
} }
} }