01a057c66c
Яндекс отдавал по строке на КАЖДЫЙ филиал (дедуп по id точки) — 214 строк, из них хлам-повторы одной сети (Корунд ×15). Новый YandexListParser дедупит по SLUG (код фирмы от источника /maps/org/<slug>/id): одна фирма = одна строка, разные написания одной фирмы склеены, разные фирмы с разным кодом раздельны. Код справочника (ya:slug) уходит в union-find склейку как опознавательный признак. Живьём 214 -> 94. TDD, 215/215 (unit+feature) зелёные. НЕ прод. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
90 lines
4.5 KiB
PHP
90 lines
4.5 KiB
PHP
<?php
|
||
|
||
declare(strict_types=1);
|
||
|
||
use App\Services\Autopodbor\AutopodborDedup;
|
||
use App\Services\Autopodbor\AutopodborNormalizer;
|
||
|
||
function mergeService(): AutopodborDedup
|
||
{
|
||
return new AutopodborDedup(new AutopodborNormalizer);
|
||
}
|
||
|
||
it('склеивает конкурента, попавшего и по имени, и по домену (одна группа)', function () {
|
||
$merged = mergeService()->mergeCompetitors([
|
||
['name' => 'Драйв займ'], // только имя (из канала В)
|
||
['name' => 'Драйв Займ', 'site_url' => 'https://драйвзайм.рф/'], // имя + домен (из канала А)
|
||
]);
|
||
|
||
// имя «драйвзайм» = корень домена «драйвзайм» → одна карточка
|
||
expect($merged)->toHaveCount(1);
|
||
expect($merged[0]['site_url'])->toBe('https://драйвзайм.рф/');
|
||
});
|
||
|
||
it('склеивает по общему домену при разном написании имени', function () {
|
||
$merged = mergeService()->mergeCompetitors([
|
||
['name' => 'Окна Комфорт', 'site_url' => 'https://okna-komfort.ru/contacts'],
|
||
['name' => 'ОКНА-КОМФОРТ', 'site_url' => 'okna-komfort.ru'],
|
||
]);
|
||
|
||
expect($merged)->toHaveCount(1);
|
||
});
|
||
|
||
it('склеивает по общему телефону', function () {
|
||
$merged = mergeService()->mergeCompetitors([
|
||
['name' => 'Фирма А', 'phones' => ['73912920000']],
|
||
['name' => 'Фирма Б', 'phones' => ['73912920000', '79991112233']],
|
||
]);
|
||
|
||
expect($merged)->toHaveCount(1);
|
||
expect($merged[0]['phones'])->toContain('73912920000')->toContain('79991112233');
|
||
});
|
||
|
||
it('объединяет ссылки справочников и телефоны внутри группы', function () {
|
||
$merged = mergeService()->mergeCompetitors([
|
||
['name' => 'X', 'site_url' => 'x.ru', 'directory_urls' => ['https://2gis.ru/firm/1'], 'phones' => ['71112223344']],
|
||
['name' => 'X', 'site_url' => 'https://x.ru/', 'directory_urls' => ['https://yandex.ru/maps/org/x/2'], 'phones' => ['75556667788']],
|
||
]);
|
||
|
||
expect($merged)->toHaveCount(1);
|
||
expect($merged[0]['directory_urls'])->toContain('https://2gis.ru/firm/1')->toContain('https://yandex.ru/maps/org/x/2');
|
||
expect($merged[0]['phones'])->toContain('71112223344')->toContain('75556667788');
|
||
});
|
||
|
||
it('склеивает по общему коду справочника (slug Яндекса), даже при разном написании имени', function () {
|
||
// Один и тот же «КрасЛомбард», но имя записано по-разному → по имени НЕ сойдётся.
|
||
// Спасает опознавательный код фирмы от Яндекса (slug) — это признак источника, не догадка.
|
||
$merged = mergeService()->mergeCompetitors([
|
||
['name' => 'КрасЛомбард', 'directory_keys' => ['ya:kraslombard'], 'directory_urls' => ['https://yandex.ru/maps/org/kraslombard/333']],
|
||
['name' => 'Красломбард 24 Взлётка', 'directory_keys' => ['ya:kraslombard'], 'directory_urls' => ['https://yandex.ru/maps/org/kraslombard/444']],
|
||
]);
|
||
|
||
expect($merged)->toHaveCount(1)
|
||
->and($merged[0]['directory_urls'])->toHaveCount(2);
|
||
});
|
||
|
||
it('не склеивает разных конкурентов', function () {
|
||
$merged = mergeService()->mergeCompetitors([
|
||
['name' => 'Окна Комфорт', 'site_url' => 'okna-komfort.ru'],
|
||
['name' => 'Пластика Окон', 'site_url' => 'plastika.ru'],
|
||
]);
|
||
|
||
expect($merged)->toHaveCount(2);
|
||
});
|
||
|
||
it('вычитает самого клиента (по домену и по имени)', function () {
|
||
$merged = mergeService()->mergeCompetitors(
|
||
[
|
||
['name' => 'Мой Бизнес', 'site_url' => 'moy-biznes.ru'], // это сам клиент по домену
|
||
['name' => 'Драйв займ', 'site_url' => 'драйвзайм.рф'],
|
||
['name' => 'Мой Бизнес Плюс'], // сам клиент по имени
|
||
],
|
||
clientKeys: ['https://moy-biznes.ru', 'Мой Бизнес Плюс'],
|
||
);
|
||
|
||
$names = array_column($merged, 'name');
|
||
expect($names)->not->toContain('Мой Бизнес');
|
||
expect($names)->not->toContain('Мой Бизнес Плюс');
|
||
expect($names)->toContain('Драйв займ');
|
||
});
|