NovinkaZverejnili sme 50+ Laravel balíkov ako open source
Custom AI apps, agents and automation — Roundly ConsultingRoundly
Všetky balíky

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 kryptomien

Odoslaní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.