k; } public function servesOperators(): array { return $this->ops; } public function priceKopecks(string $operator): int { return 100; } public function send(SmsOutgoing $m): SmsSendResult { return new SmsSendResult('x', 1, 100, CarbonImmutable::now()); } }; } it('по умолчанию резерва нет — второй канал не отдаётся', function () { config()->set('services.sms.failover_to_universal', false); $router = new SmsRouter([ failover_provider('mts', ['mts']), failover_provider('smsc', ['*']), ]); expect($router->fallbackFor('mts'))->toBeNull(); }); it('при включённом флаге резерв — универсал', function () { config()->set('services.sms.failover_to_universal', true); $router = new SmsRouter([ failover_provider('mts', ['mts']), failover_provider('smsc', ['*']), ]); expect($router->fallbackFor('mts')?->key())->toBe('smsc'); });