0131ecfc47
Качество. Привязанные клиентом карточки 2ГИС/Яндекс теперь используются как «земля» и якорь холдинга (раньше выбрасывались). Слепой поиск по имени берётся только при наличии якоря; AnchorGate: пустой якорь → drop (было keep-всё — корень шума). Без сайта чужие фирмы по широкому имени («Притяжение» → стоматология, салоны, эротический магазин) больше не попадают в карточку конкурента. Доказано на живых данных (Сибагропромстрой): свежий полный сбор — 0 салонов, только номера застройщика. Скорость (за флагом AUTOPODBOR_PHONE_REVERSE_PARALLEL, ВЫКЛ по умолчанию). ParallelPhoneReverse крутит 2ГИС- и Яндекс-разворот ОДНОВРЕМЕННО (итог по времени = max, не сумма; оба источника отрабатывают полностью — ничего не режется). Сверка последовательно vs параллельно: данные один в один, потерь нет. Таймаут подпроцесса 600с (драйвер process иначе берёт дефолт Symfony 60с и убивал разворот). Тесты: AnchorGate (пустой якорь → drop; телефон-якорь режет чужое), якорь привязанной карточки режет салоны, ParallelPhoneReverse (слияние на sync-драйвере). Весь Autopodbor 464/464, Pint чист. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
55 lines
3.1 KiB
PHP
55 lines
3.1 KiB
PHP
<?php
|
|
|
|
use App\Services\Autopodbor\Agent\Study\ParallelPhoneReverse;
|
|
use App\Services\Autopodbor\Agent\Study\PhoneExpansionResult;
|
|
use App\Services\Autopodbor\Agent\Study\PhoneReverse;
|
|
|
|
// ParallelPhoneReverse крутит 2ГИС- и Яндекс-разворот ОДНОВРЕМЕННО (итог = max, не сумма), затем
|
|
// сливает находки: сайты дедуп по домену, телефоны по цифрам, 2ГИС (первый) выигрывает при совпадении.
|
|
// В тестах — драйвер concurrency 'sync' (детерминированно, в том же процессе).
|
|
|
|
function parFakeReverse(array $sites, array $phones): PhoneReverse
|
|
{
|
|
return new class($sites, $phones) implements PhoneReverse
|
|
{
|
|
public function __construct(private array $sites, private array $phones) {}
|
|
|
|
public function expand(string $gisSlug, array $seedPhones, array $seedDomains, string $yandexSlug = ''): PhoneExpansionResult
|
|
{
|
|
return new PhoneExpansionResult($this->sites, $this->phones);
|
|
}
|
|
};
|
|
}
|
|
|
|
beforeEach(fn () => config()->set('concurrency.default', 'sync'));
|
|
|
|
it('сливает находки обоих разворотов: дедуп сайтов и телефонов, 2ГИС выигрывает', function () {
|
|
$gis = parFakeReverse(
|
|
sites: [['domain' => 'a.ru', 'site_url' => 'https://a.ru', 'card_url' => 'gis/a']],
|
|
phones: [['digits' => '73912000001', 'url' => 'gis/1', 'source' => '2ГИС'],
|
|
['digits' => '73912000009', 'url' => 'gis/9', 'source' => '2ГИС']],
|
|
);
|
|
$yandex = parFakeReverse(
|
|
sites: [['domain' => 'b.ru', 'site_url' => 'https://b.ru', 'card_url' => 'ya/b'],
|
|
['domain' => 'a.ru', 'site_url' => 'https://a.ru', 'card_url' => 'ya/a']], // дубль домена a.ru
|
|
phones: [['digits' => '73912000002', 'url' => 'ya/2', 'source' => 'Яндекс'],
|
|
['digits' => '73912000009', 'url' => 'ya/9', 'source' => 'Яндекс']], // дубль номера ...009
|
|
);
|
|
|
|
$res = (new ParallelPhoneReverse($gis, $yandex))->expand('krasnoyarsk', ['73912000000'], [], '62/krasnoyarsk');
|
|
|
|
// сайты: a.ru (от 2ГИС) + b.ru — дубль a.ru от Яндекса отброшен
|
|
expect($res->sites)->toHaveCount(2)
|
|
->and(array_column($res->sites, 'domain'))->toEqualCanonicalizing(['a.ru', 'b.ru'])
|
|
->and(collect($res->sites)->firstWhere('domain', 'a.ru')['card_url'])->toBe('gis/a'); // 2ГИС выиграл
|
|
|
|
// телефоны: 001, 009 (2ГИС), 002 — дубль 009 от Яндекса отброшен
|
|
expect(array_column($res->phones, 'digits'))->toEqualCanonicalizing(['73912000001', '73912000009', '73912000002'])
|
|
->and(collect($res->phones)->firstWhere('digits', '73912000009')['source'])->toBe('2ГИС');
|
|
});
|
|
|
|
it('пустые находки — пустой результат', function () {
|
|
$res = (new ParallelPhoneReverse(parFakeReverse([], []), parFakeReverse([], [])))->expand('krasnoyarsk', [], [], '');
|
|
expect($res->sites)->toBe([])->and($res->phones)->toBe([]);
|
|
});
|