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

Dva pomocníci, oba na fasáde. SafeFetch::fake() zaznamená každý verdikt a zároveň ho vykoná — ponechá skutočnú ochranu, takže privátna adresa sa aj tak odmietne. SafeFetch::fakeDns() odpovedá na preklady mien z tabuľky. Ani jeden nenahrádza HTTP požiadavky: na tie odpovedzte cez Http::fake().

SafeFetch::fake() — záznam každého verdiktu

use RoundlyConsulting\SafeFetch\DataTransferObjects\VettedDestination;
use RoundlyConsulting\SafeFetch\Enums\Reason;

$fake = SafeFetch::fake(['pinned.example' => '151.101.1.1']);   // optional DNS pins
Http::fake(['*' => Http::response('ok')]);

// The code under test:
SafeFetch::fetch('https://feed.example/rss');
Http::safe()->post('https://hooks.example/a', ['event' => 'ping']);
SafeFetch::allows('https://10.0.0.1/');

$fake->assertFetched('https://feed.example/rss');                // or a Closure(string $url): bool
$fake->assertVetted('https://hooks.example/a');                  // or a Closure(RecordedVet): bool
$fake->assertNotVetted('https://other.example/');
$fake->assertRefused('https://10.0.0.1/', Reason::Blocked);      // reason optional
$fake->assertGuardedRequestSent(fn (VettedDestination $hop) => $hop->host === 'hooks.example');
$fake->assertNothingDownloaded();
$fake->recorded();                                               // list<RecordedVet>

SafeFetch::assertRefused('https://10.0.0.1/', Reason::Blocked);  // the same assertions, on the facade
  • Nahradí manažéra za fasádou aj v kontajneri — Testing\SafeFetchFake dedí zo SafeFetchManager, takže aj injektovaný manažér je fake.
  • Zaznamenáva vet(), allows(), precheck() (via precheck, bez overeného cieľa — nič sa neprekladá), každý krok chránenej požiadavky (via http) a každé fetch() a download(). URL adresy sa porovnávajú tak, ako sú zapísané, alebo po prestavaní oboch spôsobom ochrany.
  • Odovzdajte ['host' => 'adresa'] (alebo zoznam adries, prípadne [] pre neprekladateľné meno) na pripnutie mien. Nepripnuté mená sa preložia na verejnú 93.184.216.34; ->strictDns() z nich spraví neprekladateľné a ->dns() vráti tabuľku.
  • Chránená požiadavka, na ktorú neodpovedal žiadny stub Http::fake(), sa odmietne ešte pred vytočením s LogicException — fetch() a download() ju vyhodia bez zmeny, nikdy ako FetchFailed — takže test, ktorý zabudol na Http::fake(), sa nikdy nedostane na skutočný server. ->allowRealRequests() ju pustí.
  • Po nainštalovaní fake sa dá každé overenie volať aj na fasáde.

Overenia

OvereniePrejde, keď
assertVetted(string|Closure $url)URL adresa bola posúdená (vet, allows, precheck, krok), alebo callbacku zodpovedal niektorý verdikt.
assertNotVetted(string $url)URL adresa nebola nikdy posúdená.
assertRefused(string $url, ?Reason $reason = null)URL adresa bola odmietnutá (z dôvodu $reason, ak je zadaný).
assertNothingRefused()Žiadny verdikt nebol odmietnutím — chybová správa vypíše každú odmietnutú URL adresu a jej dôvod.
assertNothingVetted()Nič nebolo posúdené.
assertFetched(string|Closure $url) · assertNothingFetched()fetch() bol (nebol) pre ňu zavolaný.
assertDownloaded(string|Closure $url) · assertNothingDownloaded()download() bol (nebol) pre ňu zavolaný.
assertGuardedRequestSent(?Closure $callback = null)Chránená požiadavka (Http::safe(), guard(), http(), fetch(), download()) prešla ochranou v kroku, ktorý callback prijme.

Zaznamenané verdikty

recorded() vráti list<Testing\RecordedVet>, jeden na každý verdikt v poradí — tvar, ktorý dostane callback assertVetted(fn (RecordedVet $vet) => …):

PoleVýznam
url (string)URL adresa tak, ako bola odovzdaná.
via (string)vet, allows, precheck, alebo http pre krok chránenej požiadavky (Http::safe(), guard(), http(), fetch(), download()).
vetted (?VettedDestination)Prijatý cieľ; null pri odmietnutí a pri každom precheck (nič sa neprekladá).
reason (?Reason)Prečo bola odmietnutá; null, ak prešla.
refused(): boolreason !== null.

SafeFetch::fakeDns() — DNS tabuľka

$dns = SafeFetch::fakeDns([
    'hooks.example' => '93.184.216.34',
    'dual.example' => ['93.184.216.34', '2606:4700::1111'],
    'gone.example' => [],                       // does not resolve
]);
$dns->resolve('cdn.example', '151.101.1.1');    // pins add up across calls
$dns->unresolvable('hooks.example');

Http::fake(['hooks.example/*' => Http::response('ok')]);
MetódaČo robí
resolve(string $host, string|array $addresses)Pripne meno na jednu alebo viac adries; pripnutia sa sčítavajú a dajú sa reťaziť.
unresolvable(string $host)Meno sa nepreloží.
lookups()Prekladané mená v poradí.
assertLookedUp(string $host, ?int $times = null)Meno bolo preložené (presne $times-krát, ak je zadané).
assertNotLookedUp(string $host) · assertNothingLookedUp()Meno, ani žiadne iné meno, nebolo preložené.
  • Meno, ktoré tabuľka nedostala, sa nepreloží, takže test sa nikdy nedostane k skutočnému DNS.
  • Mená sa porovnávajú tak, ako ich zapisuje ochrana — malými písmenami, bez koncovej bodky, ako punycode.
  • Pripnutie priamo zapísanej adresy, niečoho, čo nie je meno (/?#@:[]), alebo niečoho, čo nie je adresa, vyhodí InvalidArgumentException. localhost a *.localhost pripnúť možno — dôveryhodný privátny hostiteľ sa prekladá.
  • fakeDns() a $fake->dns() vracajú ten istý Testing\FakeHostResolver; tabuľka žije v kontajneri a končí s testom.

Pripnutie v teste

Laravel odovzdá callbacku stubu voľby požiadavky, takže test pripnutie uvidí:

$dns = SafeFetch::fakeDns(['hooks.example.com' => '93.184.216.34', 'internal.example.com' => '10.0.0.5']);
Http::fake(fn (Request $request, array $options) => Http::response($options['curl'][CURLOPT_RESOLVE][0]));

$pinned = $safeFetch->guard(Http::timeout(10), $policy)->post('https://hooks.example.com/in', ['event' => 'ping'])->body();

$dns->assertLookedUp('hooks.example.com', 1);                    // $pinned === 'hooks.example.com:443:93.184.216.34'

Výnimky vo vlastných dvojníkoch

Pomenované konštruktory (pozrite Verdikty a výnimky) umožnia testovaciemu dvojníkovi vyhodiť presne to, čo vyhadzuje balík.

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.