Testovanie
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
| Overenie | Prejde, 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) => …):
| Pole | Vý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(): bool | reason !== 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 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.