diff --git a/app-modules/catalog/src/Http/Resources/EvCompanyResource.php b/app-modules/catalog/src/Http/Resources/EvCompanyResource.php index 31fa521..2e5401e 100644 --- a/app-modules/catalog/src/Http/Resources/EvCompanyResource.php +++ b/app-modules/catalog/src/Http/Resources/EvCompanyResource.php @@ -23,7 +23,7 @@ class EvCompanyResource extends JsonResource 'mm_description' => $this->mm_description, 'contact' => $this->contact, 'address' => $this->address, - 'logo' => $this->logo, + 'logo' => $this->logo_url, ]; } } diff --git a/app-modules/catalog/src/Models/EvCompany.php b/app-modules/catalog/src/Models/EvCompany.php index baaebf3..c595c29 100644 --- a/app-modules/catalog/src/Models/EvCompany.php +++ b/app-modules/catalog/src/Models/EvCompany.php @@ -2,8 +2,10 @@ namespace Modules\Catalog\Models; +use Illuminate\Database\Eloquent\Casts\Attribute; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; +use Illuminate\Support\Facades\Storage; use Illuminate\Support\Str; use Modules\Catalog\Database\Factories\EvCompanyFactory; use Spatie\Activitylog\Models\Concerns\LogsActivity; @@ -72,4 +74,26 @@ class EvCompany extends Model 'is_active' => 'boolean', ]; } + + /** + * `logo` is stored as the disk-relative path Filament's FileUpload + * writes (e.g. "logos/xxx.png"), not a URL — API consumers need a full + * absolute URL to render it directly. Guards against the disk itself + * already returning an absolute URL (e.g. an s3 disk), so this stays + * correct if the storage disk ever changes from local. + */ + public function logoUrl(): Attribute + { + return Attribute::make( + get: function (): ?string { + if (blank($this->logo)) { + return null; + } + + $url = Storage::disk(config('filesystems.default'))->url($this->logo); + + return str($url)->startsWith(['http://', 'https://']) ? $url : url($url); + }, + ); + } } diff --git a/app-modules/catalog/tests/Feature/CatalogReadApiTest.php b/app-modules/catalog/tests/Feature/CatalogReadApiTest.php index ea1966c..3b3e837 100644 --- a/app-modules/catalog/tests/Feature/CatalogReadApiTest.php +++ b/app-modules/catalog/tests/Feature/CatalogReadApiTest.php @@ -1,6 +1,7 @@ assertJsonFragment(['id' => $active->id]); }); +test('returns the company logo as a full absolute url', function () { + $company = EvCompany::factory()->create(['is_active' => true, 'logo' => 'logos/example.png']); + + $this->withHeader('Authorization', "Bearer {$this->token}") + ->getJson('/api/v1/companies') + ->assertSuccessful() + ->assertJsonFragment(['logo' => url(Storage::disk(config('filesystems.default'))->url($company->logo))]); +}); + +test('returns a null logo when the company has none', function () { + EvCompany::factory()->create(['is_active' => true, 'logo' => null]); + + $this->withHeader('Authorization', "Bearer {$this->token}") + ->getJson('/api/v1/companies') + ->assertSuccessful() + ->assertJsonFragment(['logo' => null]); +}); + test('lists active destinations', function () { $active = Destination::factory()->create(['is_active' => true]); Destination::factory()->create(['is_active' => false]);