Fault injection: timeout, 500, and a slow trickle

Every test mocks a fast success, and every production incident is one of the four failure modes nobody wrote a test for.

// the four worth covering, per integration
Http::fake([
    'a/*' => fn () => throw new ConnectionException('timed out'),
    'b/*' => Http::response('<html>502</html>', 502),
    'c/*' => Http::response('{"partial": ', 200),   // truncated
    'd/*' => Http::response(['ok' => true], 200)->delay(30),
]);

The slow trickle is the one that is hardest to simulate and causes the worst outages, because a response that arrives at one byte per second passes every check except the timeout — and a client without a total timeout, only a connect timeout, waits forever. Each of these should produce a defined behaviour rather than an unhandled exception, and writing the test is how you find out there is no defined behaviour.