Files
portal/app/tests/Support/Imitation/FakeDaDataPhoneClient.php
T
2026-06-03 15:35:46 +03:00

100 lines
3.4 KiB
PHP

<?php
declare(strict_types=1);
namespace Tests\Support\Imitation;
use App\Services\DaData\DaDataException;
use App\Services\DaData\DaDataPhoneClient;
use App\Services\DaData\DaDataPhoneResponse;
/**
* Детерминированный фейк DaData-клиента для тестов имитации (Phase 1).
*
* Позволяет прогонять каскад LeadRegionResolver без внешних HTTP-вызовов:
* заранее регистрируем ответы по номеру телефона через stub(), затем
* биндим этот фейк в контейнер вместо реального DaDataPhoneClient.
*
* Использование:
* $fake = new FakeDaDataPhoneClient();
* $fake->stub('79990000077', qc: 0, region: 'Москва', provider: 'МТС');
* app()->instance(DaDataPhoneClient::class, $fake);
*
* Task 1 — Phase 1 Portal Client Imitation Harness.
* Spec: docs/superpowers/specs/2026-06-03-portal-client-imitation-phase1-design.md
*/
class FakeDaDataPhoneClient extends DaDataPhoneClient
{
/**
* @var array<string, DaDataPhoneResponse|null> phone => response (null = throw DaDataException)
*/
private array $stubs = [];
/**
* Переопределяем конструктор без вызова parent, чтобы не требовать HttpFactory в тестах.
*/
public function __construct() {}
/**
* Зарегистрировать детерминированный ответ для номера телефона.
*
* @param int $qc Код качества DaData (0=хорошо, 1=не уточнён, 2=мусор, 3=изменён, 7=иностранец)
*/
public function stub(
string $phone,
int $qc,
?string $region = null,
?string $provider = null,
): self {
$this->stubs[$phone] = new DaDataPhoneResponse(
qc: $qc,
qcConflict: null,
type: null,
phone: $phone,
provider: $provider,
region: $region,
city: null,
timezone: null,
raw: [
'qc' => $qc,
'provider' => $provider,
'region' => $region,
'phone' => $phone,
],
);
return $this;
}
/**
* Зарегистрировать выброс DaDataException для номера телефона.
* Используется для тестирования ветки деградации (Россвязь-fallback).
*/
public function stubThrows(string $phone): self
{
$this->stubs[$phone] = null; // null = throw
return $this;
}
/**
* Возвращает заранее зарегистрированный ответ или бросает DaDataException.
*
* @throws DaDataException Если стаб не зарегистрирован или зарегистрирован как throw.
*/
public function cleanPhone(string $phone): DaDataPhoneResponse
{
if (! array_key_exists($phone, $this->stubs)) {
throw new DaDataException("FakeDaDataPhoneClient: no stub registered for phone {$phone}");
}
$response = $this->stubs[$phone];
if ($response === null) {
throw new DaDataException("FakeDaDataPhoneClient: stubbed to throw for phone {$phone}");
}
return $response;
}
}