k; } public function servesOperators(): array { return $this->ops; } public function priceKopecks(string $operator): int { return $this->price; } public function send(SmsOutgoing $m): SmsSendResult { return new SmsSendResult('x', 1, $this->price, CarbonImmutable::now()); } }; } it('билайновский номер уходит через Билайн, а не через дорогого универсала', function () { $router = new SmsRouter([ fakeProviderFor('mts', ['*'], 990), fakeProviderFor('beeline', ['ВымпелКом'], 475), ]); expect($router->pick('ВымпелКом')?->key())->toBe('beeline'); }); it('чужой оператор уходит через универсала', function () { $router = new SmsRouter([ fakeProviderFor('mts', ['*'], 990), fakeProviderFor('beeline', ['ВымпелКом'], 475), ]); expect($router->pick('МегаФон')?->key())->toBe('mts'); }); it('при неизвестном операторе берёт универсала', function () { $router = new SmsRouter([fakeProviderFor('mts', ['*'], 990)]); expect($router->pick('')?->key())->toBe('mts'); }); it('без подходящего провайдера возвращает null — номер будет пропущен, деньги целы', function () { $router = new SmsRouter([fakeProviderFor('beeline', ['ВымпелКом'], 475)]); expect($router->pick('МегаФон'))->toBeNull(); }); it('из двух подходящих выбирает дешёвого', function () { $router = new SmsRouter([ fakeProviderFor('dear', ['МТС'], 900), fakeProviderFor('cheap', ['МТС'], 503), ]); expect($router->pick('МТС')?->key())->toBe('cheap'); });