a42647c6fe
Шаг 2 «Конкурентного поля»: один номер встречается в нескольких местах — код сайта плюс карточки 2ГИС/Яндекс с разными адресами. Раньше хранилось одно provenance_url/label — список терялся. Теперь сквозной провод движок→контракт→джоб→БД→API; фронт уже умел показывать кликабельным списком с подтверждениями. - autopodbor_sources +3 колонки where_found/office/confirmations миграция 2026_06_30_120000, идемпотентная, RLS-review APPROVE 7/7 - canon-sync schema.sql v8.59 плюс CHANGELOG, вкл. catch-up phone_type/box 29.06 - тесты бэкенда автоподбора 122/122 НЕ на проде, воркстри avtopodbor. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
102 lines
5.7 KiB
PHP
102 lines
5.7 KiB
PHP
<?php
|
|
|
|
use App\Services\Autopodbor\Agent\Dto\StudyCompetitorRequest;
|
|
use App\Services\Autopodbor\Agent\FakeCompetitorAgent;
|
|
use App\Services\Autopodbor\Agent\Fetch\DirectoryCard;
|
|
use App\Services\Autopodbor\Agent\Fetch\FetchedSite;
|
|
use App\Services\Autopodbor\Agent\RealCompetitorAgent;
|
|
use Tests\Unit\Autopodbor\Agent\FakeFetcher;
|
|
|
|
it('studyCompetitor: настоящий номер из кода+2ГИС наверху, подменный внизу, сайт отдельной строкой', function () {
|
|
$fetcher = new FakeFetcher(
|
|
sites: [
|
|
'https://k.ru' => new FetchedSite(
|
|
url: 'https://k.ru',
|
|
rawHtml: '<a href="tel:+73912920000">x</a><script src="//cdn.callibri.ru/x.js"></script><span>8(391)111-22-33</span>',
|
|
visiblePhones: ['8(391)111-22-33'],
|
|
),
|
|
],
|
|
cards: [
|
|
'https://2gis.ru/firm/1' => [
|
|
new DirectoryCard(number: '8(391)292-00-00', office: 'Единая справочная', url: 'https://2gis.ru/firm/1', source: '2ГИС'),
|
|
],
|
|
],
|
|
);
|
|
$agent = new RealCompetitorAgent($fetcher, new FakeCompetitorAgent);
|
|
|
|
$res = $agent->studyCompetitor(new StudyCompetitorRequest(
|
|
competitor: ['name' => 'КрасЛомбард', 'site_url' => 'k.ru', 'directory_urls' => ['https://2gis.ru/firm/1']],
|
|
regionCode: 391,
|
|
));
|
|
|
|
$calls = array_values(array_filter($res->sources, fn ($s) => $s['signal_type'] === 'call'));
|
|
$sites = array_values(array_filter($res->sources, fn ($s) => $s['signal_type'] === 'site'));
|
|
|
|
// настоящий 292-00-00 (код+2ГИС = 2 подтверждения) выше подменного 111-22-33
|
|
expect($calls[0]['identifier'])->toBe('73912920000');
|
|
expect($calls[0]['phone_kind'])->toBe('real');
|
|
expect(end($calls)['phone_kind'])->toBe('substitute');
|
|
// сайт конкурента — отдельной строкой
|
|
expect(collect($sites)->pluck('identifier'))->toContain('k.ru');
|
|
});
|
|
|
|
it('телефонная строка несёт список «где нашли», офис и число подтверждений', function () {
|
|
$fetcher = new FakeFetcher(
|
|
sites: ['https://k.ru' => new FetchedSite(url: 'https://k.ru', rawHtml: '<a href="tel:+73912920000">x</a>')],
|
|
cards: [
|
|
'https://2gis.ru/firm/1' => [new DirectoryCard(number: '8(391)292-00-00', office: 'Единая справочная', url: 'https://2gis.ru/firm/1', source: '2ГИС')],
|
|
],
|
|
);
|
|
$agent = new RealCompetitorAgent($fetcher, new FakeCompetitorAgent);
|
|
$res = $agent->studyCompetitor(new StudyCompetitorRequest(
|
|
competitor: ['name' => 'КрасЛомбард', 'site_url' => 'k.ru', 'directory_urls' => ['https://2gis.ru/firm/1']],
|
|
regionCode: 391,
|
|
));
|
|
|
|
$top = array_values(array_filter($res->sources, fn ($s) => $s['signal_type'] === 'call'))[0];
|
|
// 292-00-00 найден в коде сайта и в 2ГИС → 2 подтверждения, 2 места «где нашли»
|
|
expect($top['confirmations'])->toBe(2);
|
|
expect($top['where_found'])->toHaveCount(2);
|
|
expect(collect($top['where_found'])->pluck('label'))->toContain('в коде сайта');
|
|
expect(collect($top['where_found'])->pluck('label'))->toContain('2ГИС');
|
|
expect($top['office'])->toBe('Единая справочная');
|
|
// адрес/ссылка 2ГИС в списке кликабельны
|
|
expect(collect($top['where_found'])->pluck('url'))->toContain('https://2gis.ru/firm/1');
|
|
});
|
|
|
|
it('строка-сайт тоже несёт where_found и одно подтверждение', function () {
|
|
$fetcher = new FakeFetcher(
|
|
sites: ['https://k.ru' => new FetchedSite(url: 'https://k.ru', rawHtml: '<a href="tel:+73912920000">x</a>')],
|
|
cards: [],
|
|
);
|
|
$agent = new RealCompetitorAgent($fetcher, new FakeCompetitorAgent);
|
|
$res = $agent->studyCompetitor(new StudyCompetitorRequest(
|
|
competitor: ['name' => 'КрасЛомбард', 'site_url' => 'k.ru', 'directory_urls' => []],
|
|
regionCode: 391,
|
|
));
|
|
|
|
$site = array_values(array_filter($res->sources, fn ($s) => $s['signal_type'] === 'site'))[0];
|
|
expect($site['confirmations'])->toBe(1);
|
|
expect($site['where_found'])->toHaveCount(1);
|
|
expect($site['where_found'][0]['url'])->toBe('https://k.ru');
|
|
});
|
|
|
|
it('сводит филиалы из разных справочников: больше подтверждений — выше', function () {
|
|
$fetcher = new FakeFetcher(
|
|
sites: ['https://k.ru' => new FetchedSite(url: 'https://k.ru', rawHtml: '<a href="tel:+73912920000">x</a>')],
|
|
cards: [
|
|
'https://2gis.ru/firm/1' => [new DirectoryCard(number: '8(391)292-00-00', office: 'Справочная', url: 'https://2gis.ru/firm/1', source: '2ГИС')],
|
|
'https://yandex.ru/maps/2' => [new DirectoryCard(number: '8(391)281-70-70', office: 'Кр. рабочий, 61', url: 'https://yandex.ru/maps/2', source: 'Яндекс.Карты')],
|
|
],
|
|
);
|
|
$agent = new RealCompetitorAgent($fetcher, new FakeCompetitorAgent);
|
|
$res = $agent->studyCompetitor(new StudyCompetitorRequest(
|
|
competitor: ['name' => 'КрасЛомбард', 'site_url' => 'k.ru', 'directory_urls' => ['https://2gis.ru/firm/1', 'https://yandex.ru/maps/2']],
|
|
regionCode: 391,
|
|
));
|
|
$calls = array_values(array_filter($res->sources, fn ($s) => $s['signal_type'] === 'call'));
|
|
// 292-00-00: код + 2ГИС = 2 подтверждения → выше, чем 281-70-70 (только Яндекс = 1)
|
|
expect($calls[0]['identifier'])->toBe('73912920000');
|
|
expect(collect($calls)->pluck('identifier'))->toContain('73912817070');
|
|
});
|