81 lines
3.1 KiB
PHP
81 lines
3.1 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
use App\Services\DaData\DaDataException;
|
|
use App\Services\DaData\DaDataPhoneClient;
|
|
use App\Services\DaData\DaDataTimeoutException;
|
|
use Illuminate\Http\Client\ConnectionException;
|
|
use Illuminate\Support\Facades\Http;
|
|
|
|
it('parses qc=0 mobile response into DTO', function (): void {
|
|
Http::fake(['cleaner.dadata.ru/*' => Http::response([[
|
|
'qc' => 0, 'qc_conflict' => 0, 'type' => 'Мобильный', 'phone' => '+7 921 555-12-34',
|
|
'provider' => 'МегаФон', 'region' => 'Санкт-Петербург и область', 'city' => null, 'timezone' => 'UTC+3',
|
|
]], 200)]);
|
|
|
|
$resp = app(DaDataPhoneClient::class)->cleanPhone('79215551234');
|
|
|
|
expect($resp->qc)->toBe(0)
|
|
->and($resp->provider)->toBe('МегаФон')
|
|
->and($resp->region)->toBe('Санкт-Петербург и область')
|
|
->and($resp->type)->toBe('Мобильный')
|
|
->and($resp->raw)->toBeArray();
|
|
});
|
|
|
|
it('parses qc=3 multiple response', function (): void {
|
|
Http::fake(['cleaner.dadata.ru/*' => Http::response([[
|
|
'qc' => 3, 'region' => 'Москва', 'provider' => 'МТС', 'type' => 'Мобильный',
|
|
]], 200)]);
|
|
|
|
expect(app(DaDataPhoneClient::class)->cleanPhone('79991234567')->qc)->toBe(3);
|
|
});
|
|
|
|
it('sends Token auth, X-Secret header and json-array body', function (): void {
|
|
config(['services.dadata.api_key' => 'KEY', 'services.dadata.secret' => 'SEC']);
|
|
Http::fake(['cleaner.dadata.ru/*' => Http::response([['qc' => 0, 'region' => 'Москва']], 200)]);
|
|
|
|
app(DaDataPhoneClient::class)->cleanPhone('79161234567');
|
|
|
|
Http::assertSent(function ($request): bool {
|
|
return $request->url() === 'https://cleaner.dadata.ru/api/v1/clean/phone'
|
|
&& $request->hasHeader('Authorization', 'Token KEY')
|
|
&& $request->hasHeader('X-Secret', 'SEC')
|
|
&& $request->body() === '["79161234567"]';
|
|
});
|
|
});
|
|
|
|
it('throws DaDataTimeoutException on connection error', function (): void {
|
|
Http::fake(fn () => throw new ConnectionException('timeout'));
|
|
|
|
expect(fn () => app(DaDataPhoneClient::class)->cleanPhone('79215551234'))
|
|
->toThrow(DaDataTimeoutException::class);
|
|
});
|
|
|
|
it('throws DaDataException on persistent 5xx', function (): void {
|
|
Http::fake(['cleaner.dadata.ru/*' => Http::response('upstream error', 500)]);
|
|
|
|
expect(fn () => app(DaDataPhoneClient::class)->cleanPhone('79215551234'))
|
|
->toThrow(DaDataException::class);
|
|
});
|
|
|
|
it('retries once on 5xx then succeeds', function (): void {
|
|
Http::fakeSequence('cleaner.dadata.ru/*')
|
|
->push('upstream error', 500)
|
|
->push([['qc' => 0, 'region' => 'Москва', 'provider' => 'МТС']], 200);
|
|
|
|
$resp = app(DaDataPhoneClient::class)->cleanPhone('79161234567');
|
|
|
|
expect($resp->qc)->toBe(0);
|
|
Http::assertSentCount(2);
|
|
});
|
|
|
|
it('does not retry on 4xx client error', function (): void {
|
|
Http::fake(['cleaner.dadata.ru/*' => Http::response('bad request', 400)]);
|
|
|
|
expect(fn () => app(DaDataPhoneClient::class)->cleanPhone('79161234567'))
|
|
->toThrow(DaDataException::class);
|
|
|
|
Http::assertSentCount(1);
|
|
});
|