Files
portal/app/tests/Unit/Autopodbor/Fetch/XfetchDirectoryFetcherTest.php
T
Дмитрий bfda9f8d46 fix(автоподбор): ретрай загрузки списка филиалов 2ГИС при флаки-рендере
Живой прогон вскрыл: рендер списка 2ГИС иногда отдаёт непустую «оболочку»
без ссылок на филиалы — ретрай в XfetchClient ловит только пустой ответ,
а тут карточки терялись. XfetchDirectoryFetcher теперь повторяет загрузку
списка, пока не появятся ссылки на филиалы, до 3 раз.

Проверено вживую на kraslombard24.ru: центральный 8(391)292-00-00
подтверждён И кодом сайта, И 2ГИС с адресом «улица Ладо Кецховели, 30»;
where_found/office/confirmations доходят до БД и API. 0 фальшивок.

- тест повтора списка при флаке; бэкенд автоподбора 131/131

НЕ на проде, воркстри avtopodbor.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-30 16:27:43 +03:00

69 lines
3.2 KiB
PHP

<?php
use App\Services\Autopodbor\Agent\Fetch\PageFetcher;
use App\Services\Autopodbor\Agent\Fetch\XfetchDirectoryFetcher;
/** @param array<string,string> $pages */
function fakePages(array $pages): PageFetcher
{
return new class($pages) implements PageFetcher
{
/** @param array<string,string> $pages */
public function __construct(private array $pages) {}
public function html(string $url): string
{
return $this->pages[$url] ?? '';
}
};
}
it('обходит список 2ГИС и собирает карточки филиалов с адресом', function () {
$fake = fakePages([
'https://2gis.ru/krasnoyarsk/search/X' => '<a href="/krasnoyarsk/firm/111">ф1</a><a href="/krasnoyarsk/firm/222">ф2</a>',
'https://2gis.ru/krasnoyarsk/firm/111' => '<title>КрасЛомбард, улица Весны, 7, Красноярск — 2ГИС</title><a href="tel:+73912550000">x</a>',
'https://2gis.ru/krasnoyarsk/firm/222' => '<title>КрасЛомбард, проспект Мира, 10, Красноярск — 2ГИС</title><a href="tel:+73912920000">x</a>',
]);
$cards = (new XfetchDirectoryFetcher($fake))->directory('https://2gis.ru/krasnoyarsk/search/X');
expect($cards)->toHaveCount(2);
$byNum = collect($cards)->keyBy('number');
expect($byNum['+73912550000']->office)->toBe('улица Весны, 7');
expect($byNum['+73912550000']->source)->toBe('2ГИС');
expect($byNum['+73912920000']->office)->toBe('проспект Мира, 10');
});
it('повторяет загрузку списка 2ГИС при флаки-рендере без ссылок на филиалы', function () {
// 1-й рендер списка — «ошибочная оболочка» без ссылок (флак); 2-й — нормальный список.
$seq = new class implements PageFetcher
{
public int $listCalls = 0;
public function html(string $url): string
{
if (str_contains($url, '/branches/') || str_contains($url, '/search/')) {
$this->listCalls++;
return $this->listCalls === 1
? '<div>Подождите, идёт загрузка…</div>' // флак: ссылок на филиалы нет
: '<a href="/krasnoyarsk/firm/111">ф1</a>'; // повтор удачен
}
return '<title>КрасЛомбард, улица Весны, 7, Красноярск — 2ГИС</title><a href="tel:+73912550000">x</a>';
}
};
$cards = (new XfetchDirectoryFetcher($seq))->directory('https://2gis.ru/krasnoyarsk/branches/985');
expect($cards)->toHaveCount(1);
expect($seq->listCalls)->toBe(2); // список перезагрузили после флака
});
it('site() тянет HTML конкурента через тот же загрузчик', function () {
$fake = fakePages(['https://k.ru' => '<a href="tel:+73912920000">x</a>']);
$site = (new XfetchDirectoryFetcher($fake))->site('https://k.ru');
expect($site->url)->toBe('https://k.ru')
->and($site->rawHtml)->toContain('tel:+73912920000');
});