[0.0], $texts); } }; $assembler = new FindCompetitorsAssembler( new AggregatorFilter($nullClassifier), new AutopodborDedup(new AutopodborNormalizer), new EmbeddingRelevance($zeroEmbedder), ); return new LiveFindCompetitors( stubPages([ // выдача '2gis.ru/krasnoyarsk/search/' => autopodborFixture('2gis-search-kraslombard.html'), 'maps/?text=' => autopodborFixture('yandex-search-kraslombard.html'), // карточки '/firm/' => autopodborFixture('2gis-firm-kraslombard.html'), '/maps/org/' => autopodborFixture('yandex-org-kraslombard.html'), ]), new SearchResultsParser, new TwoGisResolver, new YandexResolver, $assembler, ); } it('живой поиск по нише → настоящий конкурент, склеенный из 2ГИС и Яндекса', function () { $res = liveEngine()->find(new FindCompetitorsRequest( regionCode: 29, // Красноярский край → город Красноярск, слаг krasnoyarsk examples: [], aboutSelf: ['ломбард', 'moy-lombard.ru'], // ниша + ВАШ сайт (другой — себя НЕ вычитаем) includeFederal: true, maxCompetitors: 20, )); $names = array_column($res->competitors, 'name'); expect($names)->toContain('КрасЛомбард'); // найден живым поиском по нише $kl = collect($res->competitors)->firstWhere('name', 'КрасЛомбард'); expect($kl['site_url'])->toBe('http://kraslombard24.ru'); // склейка одной фирмы из 2ГИС + Яндекс: в «где нашли» обе ссылки справочников expect(collect($kl['directory_urls'])->contains(fn (string $u): bool => str_contains($u, '/firm/')))->toBeTrue(); expect(collect($kl['directory_urls'])->contains(fn (string $u): bool => str_contains($u, '/maps/org/')))->toBeTrue(); }); it('свой сайт вычитается из конкурентов', function () { $res = liveEngine()->find(new FindCompetitorsRequest( regionCode: 29, examples: [], aboutSelf: ['ломбард', 'kraslombard24.ru'], // теперь КрасЛомбард = это «мы» includeFederal: true, maxCompetitors: 20, )); expect(array_column($res->competitors, 'name'))->not->toContain('КрасЛомбард'); }); it('пустая выдача → пустой список, без падения', function () { $engine = new LiveFindCompetitors( stubPages([]), // на всё '' new SearchResultsParser, new TwoGisResolver, new YandexResolver, new FindCompetitorsAssembler( new AggregatorFilter(new class implements AggregatorClassifier { public function isAggregator(string $name, ?string $siteUrl, ?string $description): ?bool { return null; } }), new AutopodborDedup(new AutopodborNormalizer), new EmbeddingRelevance(new class implements Embedder { public function embed(array $texts): array { return array_map(fn () => [0.0], $texts); } }), ), ); $res = $engine->find(new FindCompetitorsRequest(29, [], ['ничего', 'self.ru'], false, 10)); expect($res->competitors)->toBe([]); });