82 lines
2.6 KiB
PHP
82 lines
2.6 KiB
PHP
|
|
<?php
|
||
|
|
|
||
|
|
declare(strict_types=1);
|
||
|
|
|
||
|
|
use App\Services\Sms\SmsOutgoing;
|
||
|
|
use App\Services\Sms\SmsProvider;
|
||
|
|
use App\Services\Sms\SmsRouter;
|
||
|
|
use App\Services\Sms\SmsSendResult;
|
||
|
|
use Carbon\CarbonImmutable;
|
||
|
|
|
||
|
|
/** Провайдер-двойник: обслуживает заданных операторов по заданной цене. */
|
||
|
|
function fakeProviderFor(string $key, array $operators, int $price): SmsProvider
|
||
|
|
{
|
||
|
|
return new class($key, $operators, $price) implements SmsProvider
|
||
|
|
{
|
||
|
|
public function __construct(
|
||
|
|
private string $k,
|
||
|
|
private array $ops,
|
||
|
|
private int $price,
|
||
|
|
) {}
|
||
|
|
|
||
|
|
public function key(): string
|
||
|
|
{
|
||
|
|
return $this->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');
|
||
|
|
});
|