Files
portal/app/tests/Unit/Autopodbor/Fetch/CompositeFetcherTest.php
T
Дмитрий 5a65165114 feat(автоподбор): движок шага 1 пересобран под финал v4 (каналы А+В, EXA)
Замена вырожденного «одна фраза → одна страница» на §12/§11.3 финал:
- Шаг АНАЛИЗ (ChannelA\AitunnelQueryAnalyzer): описание → запросы-рубрики (мелкая модель).
- Канал А (ChannelA\CategoryScraper): скрейп категории 2ГИС с пагинацией → резолв карточек.
- Канал В (ChannelB\*): ОДНА модель sonar-reasoning-pro × 2 прохода → ТОЛЬКО имена
  федералов; стоп-лист = имена из А + примеры; сайт федерала через EXA (ExaSiteFinder),
  т.к. у федерала нет карточки в 2ГИС/Яндексе на регион.
- Оркестратор LiveFindCompetitors переписан: АНАЛИЗ→А→В→слияние→отсев→дедуп→похожесть→DTO.
- Провайдер перепрошит; config services.php +research_model/exa.
Похожесть — эмбеддер-модель (математически), резолвер/дедуп — без изменений.
Всё за тонкими границами, офлайн-тесты на фикстурах: модуль 130 unit + 74 feature зелёные.
Провайдер за флагом autopodbor.real_find; на проде не меняется.

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

50 lines
1.6 KiB
PHP

<?php
use App\Services\Autopodbor\Agent\Fetch\CompositeFetcher;
use App\Services\Autopodbor\Agent\Fetch\DirectoryCard;
use App\Services\Autopodbor\Agent\Fetch\FetchedSite;
use App\Services\Autopodbor\Agent\Fetch\Fetcher;
function onlySiteFetcher(): Fetcher
{
return new class implements Fetcher
{
public function site(string $url): FetchedSite
{
return new FetchedSite(url: $url, rawHtml: 'ИЗ-САЙТ-ЗАГРУЗЧИКА');
}
public function directory(string $url): array
{
throw new RuntimeException('directory не должен идти в site-загрузчик');
}
};
}
function onlyDirectoryFetcher(): Fetcher
{
return new class implements Fetcher
{
public function site(string $url): FetchedSite
{
throw new RuntimeException('site не должен идти в directory-загрузчик');
}
public function directory(string $url): array
{
return [new DirectoryCard(number: '+73912920000', office: 'Мира, 10', url: $url, source: '2ГИС')];
}
};
}
it('site() идёт в site-загрузчик, directory() — в directory-загрузчик', function () {
$c = new CompositeFetcher(onlySiteFetcher(), onlyDirectoryFetcher());
expect($c->site('https://k.ru')->rawHtml)->toBe('ИЗ-САЙТ-ЗАГРУЗЧИКА');
$cards = $c->directory('https://2gis.ru/x');
expect($cards)->toHaveCount(1)
->and($cards[0]->number)->toBe('+73912920000')
->and($cards[0]->source)->toBe('2ГИС');
});