Laravel 13 + Filament 5 admin panel and REST API for a non-profit developer collective, backed by the Pireon OAuth identity server. The public site is a separate, server-rendered application consuming /api/public/v1. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
149 lines
4.6 KiB
PHP
149 lines
4.6 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace Tests\Feature\Panel;
|
|
|
|
use App\Filament\Resources\Media\MediaResource;
|
|
use App\Filament\Resources\Technologies\TechnologyResource;
|
|
use App\Models\Media;
|
|
use App\Models\Project;
|
|
use App\Models\Technology;
|
|
use Database\Seeders\RolePermissionSeeder;
|
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
|
use Illuminate\Support\Facades\Queue;
|
|
use Illuminate\Support\Facades\Storage;
|
|
use PHPUnit\Framework\Attributes\Test;
|
|
use Tests\FakesPireon;
|
|
use Tests\TestCase;
|
|
|
|
/**
|
|
* The catalogue of everything uploaded, and logos on technologies.
|
|
*/
|
|
class MediaLibraryTest extends TestCase
|
|
{
|
|
use FakesPireon, RefreshDatabase;
|
|
|
|
protected function setUp(): void
|
|
{
|
|
parent::setUp();
|
|
|
|
$this->seed(RolePermissionSeeder::class);
|
|
Queue::fake();
|
|
Storage::fake(config('media.disk'));
|
|
}
|
|
|
|
#[Test]
|
|
public function the_library_lists_what_has_been_uploaded(): void
|
|
{
|
|
Project::factory()->create(['cover_image' => 'projects/una.jpg']);
|
|
|
|
$this->actingAs($this->userWithRoles('admin'));
|
|
|
|
$this->get(MediaResource::getUrl('index'))
|
|
->assertSuccessful()
|
|
->assertSee('projects/una.jpg');
|
|
}
|
|
|
|
#[Test]
|
|
public function nobody_uploads_from_the_library(): void
|
|
{
|
|
$this->actingAs($this->userWithRoles('admin'));
|
|
|
|
// Files arrive by being uploaded on a record, not from here.
|
|
$this->assertFalse(MediaResource::canCreate());
|
|
}
|
|
|
|
#[Test]
|
|
public function a_file_something_points_at_cannot_be_deleted(): void
|
|
{
|
|
Project::factory()->create(['cover_image' => 'projects/en-uso.jpg']);
|
|
$media = Media::query()->where('path', 'projects/en-uso.jpg')->sole();
|
|
|
|
$admin = $this->userWithRoles('admin');
|
|
|
|
// Deleting it would put a broken image on the public site, which is
|
|
// exactly what the health check exists to complain about.
|
|
$this->assertTrue($media->isReferenced());
|
|
$this->assertFalse($admin->can('delete', $media));
|
|
}
|
|
|
|
#[Test]
|
|
public function a_file_nothing_points_at_can(): void
|
|
{
|
|
$media = Media::factory()->create(['path' => 'projects/huerfana.jpg']);
|
|
|
|
$this->assertFalse($media->isReferenced());
|
|
$this->assertTrue($this->userWithRoles('admin')->can('delete', $media));
|
|
}
|
|
|
|
#[Test]
|
|
public function the_weight_counts_the_derived_versions_too(): void
|
|
{
|
|
$media = Media::factory()->create([
|
|
'size' => 1000,
|
|
'variants' => [
|
|
['format' => 'webp', 'width' => 400, 'path' => 'a-400.webp', 'size' => 300],
|
|
['format' => 'webp', 'width' => 800, 'path' => 'a-800.webp', 'size' => 700],
|
|
],
|
|
]);
|
|
|
|
// The number that explains where the disk went.
|
|
$this->assertSame(2000, $media->totalSize());
|
|
}
|
|
|
|
#[Test]
|
|
public function a_viewer_may_look_but_not_tidy(): void
|
|
{
|
|
$media = Media::factory()->create();
|
|
$viewer = $this->userWithRoles('viewer');
|
|
|
|
$this->assertTrue($viewer->can('media.view_any'));
|
|
$this->assertFalse($viewer->can('delete', $media));
|
|
}
|
|
|
|
#[Test]
|
|
public function a_technology_can_carry_a_logo(): void
|
|
{
|
|
$technology = Technology::factory()->create([
|
|
'name' => 'Laravel',
|
|
'logo' => 'technologies/laravel.svg',
|
|
]);
|
|
|
|
// Registered like any other upload: same media row, same processing.
|
|
$this->assertSame(1, Media::query()->where('path', 'technologies/laravel.svg')->count());
|
|
$this->assertSame('technologies/laravel.svg', $technology->logo);
|
|
}
|
|
|
|
#[Test]
|
|
public function the_logo_reaches_the_frontend_with_the_name_as_its_alt(): void
|
|
{
|
|
Technology::factory()->create([
|
|
'name' => 'Rust',
|
|
'slug' => 'rust',
|
|
'radar_ring' => 'adopt',
|
|
'logo' => 'technologies/rust.svg',
|
|
]);
|
|
|
|
$data = $this->withHeaders(['Accept-Language' => 'es'])
|
|
->getJson('/api/public/v1/radar')
|
|
->assertOk()
|
|
->json('data.0');
|
|
|
|
// A logo's description is the name of the thing, so there is nothing
|
|
// to type and nothing to get wrong.
|
|
$this->assertSame('Rust', $data['logo']['alt']);
|
|
$this->assertStringContainsString('technologies/rust.svg', $data['logo']['url']);
|
|
}
|
|
|
|
#[Test]
|
|
public function the_technology_editor_still_opens(): void
|
|
{
|
|
$technology = Technology::factory()->create(['logo' => 'technologies/x.svg']);
|
|
|
|
$this->actingAs($this->userWithRoles('admin'));
|
|
|
|
$this->get(TechnologyResource::getUrl('edit', ['record' => $technology]))->assertSuccessful();
|
|
}
|
|
}
|