Testovanie
MediaLibrary::fake() vymení manažéra za nahrávací fake a vráti ho:
use RoundlyConsulting\MediaLibrary\Facades\MediaLibrary;
$fake = MediaLibrary::fake();
$this->post('/profile/avatar', ['avatar' => UploadedFile::fake()->image('me.png')]);
$fake->assertAdded('avatar', to: $user);
$fake->assertNothingDeleted();- Nič nezapisuje — žiadny súbor na disku, žiadny riadok, žiadny job vo fronte ani event — test teda nepotrebuje reálne disky ani Storage::fake(). Každý disk, ktorý má použiť, však musí byť nakonfigurovaný vo filesystems.disks rovnako ako pri skutočnom manažérovi — samotné Storage::fake() ho nepridá.
- Zaznamená každé volanie, či prišlo cez fasádu, injektovaný MediaLibraryManager, handle for(), trait InteractsWithMedia alebo metódu modelu Media.
- Zmeny aj tak vracajú realistické výsledky: pridanie, attach a kópia vrátia neuložené Media s novým uuid, vlastníkom, skupinou, diskom, viditeľnosťou a tým istým bezpečným názvom súboru, aký uloží skutočné pridanie; presun médium prepojí v pamäti a bindDraft() vráti draft na disku a s viditeľnosťou jeho skupiny.
- Odmietne presne to, čo skutočný manažér: pravidlá prijatia skupiny (mime allowlist, limit veľkosti, rozmery obrázka) platia pri pridaní, naviazaní draftu, attach, presune, kópii aj náhrade; nenakonfigurovaný disk vyhodí DiskDoesNotExist, neuložený vlastník MediaOwnerNotSaved, withVisibility() prijme len public alebo private a neznámy či expirovaný token draftu stále vyhodí výnimku. Čítanie ide do databázy ako zvyčajne.
- remote() zostáva skutočné a nezaznamenáva sa: nič neukladá a jeho požiadavky idú cez HTTP klienta Laravelu, preto ho spojte s Http::fake() — a pre preklady DNS s MediaLibrary::fakeDns().
Asercie
Každý argument je voliteľný filter; null zodpovedá čomukoľvek:
$fake->assertAdded('avatar', to: $user);
$fake->assertAttached($logo, to: $user, bucket: 'avatar');
$fake->assertDraftBound($token, to: $user, bucket: 'avatar');
$fake->assertMoved($media, to: $otherUser, bucket: 'gallery', disk: 'cold');
$fake->assertVariantsMoved($media, disk: 'hot');
$fake->assertCopied($media, to: $otherUser, bucket: 'gallery');
$fake->assertReplaced($media);
$fake->assertDeleted($media); // clear() records one delete per media
$fake->assertRegenerated($media, only: ['thumb'], force: true);
$fake->assertDraftsPruned();
// The negative counterparts
$fake->assertNothingAdded();
$fake->assertNothingAttached();
$fake->assertNothingBound();
$fake->assertNothingMoved();
$fake->assertNoVariantsMoved();
$fake->assertNothingCopied();
$fake->assertNothingReplaced();
$fake->assertNothingDeleted();
$fake->assertNothingRegenerated();
$fake->assertDraftsNotPruned();End-to-end proti fake disku
Ak chcete reálne súbory a vygenerované varianty, fake vynechajte a pre disky skupiny použite Storage::fake():
use Illuminate\Http\UploadedFile;
use Illuminate\Support\Facades\Storage;
use RoundlyConsulting\MediaLibrary\Facades\MediaLibrary;
it('stores an avatar and generates a thumbnail', function () {
Storage::fake('cold');
Storage::fake('hot');
$user = User::factory()->create();
MediaLibrary::for($user)
->add(UploadedFile::fake()->image('me.jpg', 600, 600))
->toBucket('avatar');
$avatar = MediaLibrary::for($user)->first('avatar');
expect($avatar->hasGeneratedVariant('thumb'))->toBeTrue();
Storage::disk('cold')->assertExists($avatar->getPath());
});Suite spúšťajte s načítanou migráciou balíka (RefreshDatabase). Frontované varianty bežia v testoch synchrónne cez sync frontu, takže vygenerované varianty sú asertovateľné okamžite.
Podvrhnutie DNS pre vzdialené URL
addFromUrl(), MediaLibrary::remote() aj pravidlo SafeRemoteUrl prekladajú hosty pre ochranu pred súkromnými sieťami aj pod Http::fake() a skutočný preklad je v teste pomalý a nedeterministický. MediaLibrary::fakeDns() odpovedá na preklady ochrany z tabuľky, takže test sa k skutočnému DNS nikdy nedostane. Podvrhne sa len DNS — na samotné požiadavky odpovedzte cez Http::fake():
use Illuminate\Support\Facades\Http;
use RoundlyConsulting\MediaLibrary\Facades\MediaLibrary;
$dns = MediaLibrary::fakeDns([
'docs.example' => ['93.184.216.34', '2606:2800:220:1:248:1893:25c8:1946'],
'intranet.example' => '10.0.0.5',
]);
Http::fake(['docs.example/*' => Http::response('hello')]);
MediaLibrary::remote()->fetch('https://docs.example/a')->body; // 'hello'
MediaLibrary::remote()->fetch('https://intranet.example/'); // RemoteFileRejected (blocked)
MediaLibrary::remote()->fetch('https://other.example/'); // RemoteFileUnavailable (unresolved)
$dns->resolve('other.example', '151.101.1.1')->unresolvable('docs.example');
$dns->assertLookedUp('docs.example', times: 1);- Názov, ktorý tabuľka nedostala, sa nepreloží — remote() vyhodí RemoteFileUnavailable, addFromUrl() RemoteFileRejected. MediaLibrary::fakeDns() bez záznamov urobí nepreložiteľným každý názov — vhodný riadok do setUp() vášho základného TestCase.
- Pripnuté adresy sa posudzujú ako skutočné odpovede: súkromná, loopback, link-local či metadata adresa sa odmietne, pokiaľ ju nepovoľuje media.remote.allowed_private_hosts, a host s čo i len jednou blokovanou adresou sa odmietne.
- Názvy sa porovnávajú tak, ako ich zapisuje ochrana — bez ohľadu na veľkosť písmen, s jednou koncovou bodkou, internacionalizovaný názov v punycode tvare (s ext-intl). Priamo zadané adresy, localhost / *.localhost a povolené názvy sa nikdy neprekladajú, takže sa do tabuľky nedostanú.
- Tabuľka žije v kontajneri aplikácie: druhé volanie v tom istom teste vráti ten istý DnsFake a pridá k nemu ďalšie pripnutia, a nasledujúci test začína bez neho. Funguje s MediaLibrary::fake() aj bez neho, v ľubovoľnom poradí.
- Pripnutie, na ktoré sa ochrana nikdy nemôže opýtať, vyhodí InvalidArgumentException — priamo zadaná adresa ako názov, názov s portom, cestou, prihlasovacími údajmi či hranatými zátvorkami, prázdny zoznam adries (použite unresolvable()) alebo čokoľvek, čo nie je IP adresa.
| Metóda DnsFake | Čo robí |
|---|---|
resolve($host, $addresses) | Pripne host na jednu či viac IPv4/IPv6 adries (IPv6 bez hranatých zátvoriek); nahradí jeho skoršie pripnutie. |
unresolvable($host) | Host sa nebude prekladať — zruší skoršie pripnutie. |
lookups() | Každý názov, ktorý ochrana prekladala, v poradí, jedna položka na preklad. |
assertLookedUp($host, times:) | Preložený aspoň raz, alebo presne times-krát. |
assertNotLookedUp($host) / assertNothingLookedUp() | Nikdy nepreložený / žiadny preklad. |
Pri vypnutom media.remote.block_private_networks sťahovanie nič neposudzuje, a teda ani neprekladá; vet() a SafeRemoteUrl sa tabuľky pýtajú aj tak. Bez fakeDns() sa vymyslený host podvrhnutý cez Http::fake() — taký, ktorý sa nepreloží, alebo sa preloží na súkromnú adresu ako lokálna doména *.test — odmietne; v testovacom prostredí ho môžete aj pridať do media.remote.allowed_private_hosts alebo nastaviť media.remote.block_private_networks na false.
Prejavte lásku k open source
Tento balík je zadarmo pod licenciou MIT. Ak vám šetrí čas, jednorazový príspevok alebo členstvo na Patreone nám pomôže ho ďalej udržiavať, testovať a dokumentovať.
Ďalšie spôsoby podpory vrátane kryptomienOdoslaním daru súhlasíte s našimi podmienkami prijímania darov.
Chcete to zabudovať do svojho produktu?
Naše balíky integrujeme do zákazkových Laravel a AI riešení. Napíšte nám, na čom pracujete, a ozveme sa do 48 hodín.