Skip to content

Testing ​

Factories ​

MediaItem::factory() and MediaFolder::factory() are available once the package is installed.

FactoryStateWhat it does
MediaItemdefaultA public JPEG record (1600 x 1067) with no file behind it. Enough for lists, pickers and attachments.
MediaItemwithImage($width = 640, $height = 480)Also writes a real PNG through Spatie, so URLs and conversions work.
MediaItemdocument()A PDF record: application/pdf, type Document, no dimensions.
MediaItemprivate($ownerId = null)Private visibility. Pass the uploader's id so they can see it.
MediaFolderdefaultA public folder with a random name.
MediaFolderprivate($ownerId = null)A private folder owned by that user.
php
use Hoceineel\FilamentMediaLibrary\Models\MediaFolder;
use Hoceineel\FilamentMediaLibrary\Models\MediaItem;

$folder = MediaFolder::factory()->create(['name' => 'Campaign']);
$photo = MediaItem::factory()->withImage()->create(['folder_id' => $folder->id]);
$secret = MediaItem::factory()->private($user->id)->create();
$brochure = MediaItem::factory()->document()->create(['name' => 'Brochure']);

Disks ​

Fake the library disk so tests never touch real storage. withImage() and uploads write to it.

php
use Illuminate\Support\Facades\Storage;

beforeEach(function () {
    Storage::fake('public');
});

Use the disk name from filament-media-library.disk. The package's own tests also set media-library.queue_conversions_by_default to false so conversions run inline.

Authenticating ​

Sign in a user who can access your panel, and for a tenant panel, set the tenant:

php
use Filament\Facades\Filament;

$this->actingAs($user);
Filament::setCurrentPanel(Filament::getPanel('admin'));
Filament::setTenant($team);
Filament::bootCurrentPanel();

Call bootCurrentPanel() after setTenant() so the plugin turns on tenant scoping. The default policies allow any signed-in user, so register your own policy in the test or use Gate::before to test denials:

php
Gate::before(fn ($user, string $ability) => $ability === 'viewAny' ? false : null);

$this->get(MediaLibraryPage::getUrl(['tenant' => $team]))->assertForbidden();

Testing a form with the picker ​

A form that uses MediaPicker is tested like any Filament form. Set the field to an item id:

php
use Livewire\Livewire;

$item = MediaItem::factory()->create();

Livewire::test(CreatePost::class)
    ->fillForm(['title' => 'Launch', 'cover_id' => $item->id])
    ->call('create')
    ->assertHasNoFormErrors();

expect(Post::query()->sole()->cover_id)->toBe($item->id);

For a relationship field, pass an array of ids, and read back with getMediaLibraryItems('gallery'). The order you send is the order stored.

Testing the browser ​

MediaBrowser is a Livewire component:

php
use Hoceineel\FilamentMediaLibrary\Livewire\MediaBrowser;

MediaItem::factory()->create(['name' => 'Root photo']);

Livewire::test(MediaBrowser::class)->assertSee('Root photo');

Test the page itself with a request:

php
$this->get(MediaLibraryPage::getUrl(['tenant' => $team]))->assertOk();

Outside panels ​

Turn on the standalone mode for the test:

php
config()->set('filament-media-library.standalone.enabled', true);

Livewire::test(MediaPickerInput::class, ['name' => 'cover_id', 'image' => true])
    ->set('value', (string) $photo->id);

The picker's configuration properties are locked, so a test that tries to set() one throws Livewire's CannotUpdateLockedPropertyException. That is the behavior you want.

Running the package's suite ​

From the package root:

bash
composer test
composer test-parallel

composer test runs vendor/bin/pest. composer test-parallel runs vendor/bin/pest --parallel, which is faster; chunk directories and fake storage are scoped per worker. Other scripts: composer format (Pint) and composer analyse (PHPStan).

The suite uses Orchestra Testbench with SQLite in memory. To run it on MySQL or PostgreSQL, set DB_CONNECTION and the usual connection variables before you run Pest:

bash
DB_CONNECTION=mysql DB_HOST=127.0.0.1 DB_PORT=3306 DB_DATABASE=media_library_test DB_USERNAME=root DB_PASSWORD= vendor/bin/pest
bash
DB_CONNECTION=pgsql DB_HOST=127.0.0.1 DB_PORT=5432 DB_DATABASE=media_library_test DB_USERNAME=postgres DB_PASSWORD=secret vendor/bin/pest

DB_CONNECTION selects the connection name in database.default. Create the empty database first.

Commercial licence. One licence per production project. Terms · Privacy · Refunds