6d48503a0e
Stage 1: опознавалка фирмы по сайту/карточкам, ProposalClassifier new/actualize/archived/hidden, box=archived, bulk удалить всех ранее удалённых. Backend 249/249, front autopodbor 61/61. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
79 lines
3.3 KiB
PHP
79 lines
3.3 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
use App\Services\Autopodbor\AutopodborNormalizer;
|
|
use App\Services\Autopodbor\CompetitorIdentity;
|
|
use App\Services\Autopodbor\ProposalClassifier;
|
|
|
|
function classifier(): ProposalClassifier
|
|
{
|
|
return new ProposalClassifier(new CompetitorIdentity(new AutopodborNormalizer));
|
|
}
|
|
|
|
function grp(array $out, int $findId): array
|
|
{
|
|
foreach ($out as $row) {
|
|
if ($row['find']['id'] === $findId) {
|
|
return $row;
|
|
}
|
|
}
|
|
throw new RuntimeException("find $findId not classified");
|
|
}
|
|
|
|
it('новая — ни с чем не пересеклась', function () {
|
|
$out = classifier()->classify(
|
|
finds: [['id' => 1, 'name' => 'A', 'site_url' => 'a.ru', 'directory_urls' => []]],
|
|
existing: [['id' => 9, 'box' => 'field', 'name' => 'B', 'site_url' => 'b.ru', 'directory_urls' => []]],
|
|
);
|
|
expect(grp($out, 1)['group'])->toBe('new');
|
|
});
|
|
|
|
it('скрытая — полный дубль активной (те же опознавалки)', function () {
|
|
$out = classifier()->classify(
|
|
finds: [['id' => 1, 'name' => 'A новое имя', 'site_url' => 'a.ru', 'directory_urls' => []]],
|
|
existing: [['id' => 9, 'box' => 'field', 'name' => 'A', 'site_url' => 'a.ru', 'directory_urls' => []]],
|
|
);
|
|
expect(grp($out, 1)['group'])->toBe('hidden');
|
|
});
|
|
|
|
it('на актуализацию — совпала карточка, но новый сайт (дельта не пуста)', function () {
|
|
$out = classifier()->classify(
|
|
finds: [['id' => 1, 'name' => 'A', 'site_url' => 'a-new.ru', 'directory_urls' => ['https://2gis.ru/x/firm/111']]],
|
|
existing: [['id' => 9, 'box' => 'field', 'name' => 'A', 'site_url' => 'a.ru', 'directory_urls' => ['https://2gis.ru/x/firm/111']]],
|
|
);
|
|
$r = grp($out, 1);
|
|
expect($r['group'])->toBe('actualize')
|
|
->and($r['matched_id'])->toBe(9)
|
|
->and($r['delta_keys'])->toBe(['s:a-new.ru']);
|
|
});
|
|
|
|
it('ранее удалённая — совпала только с архивом', function () {
|
|
$out = classifier()->classify(
|
|
finds: [['id' => 1, 'name' => 'A', 'site_url' => 'a.ru', 'directory_urls' => []]],
|
|
existing: [['id' => 9, 'box' => 'archived', 'name' => 'A', 'site_url' => 'a.ru', 'directory_urls' => []]],
|
|
);
|
|
$r = grp($out, 1);
|
|
expect($r['group'])->toBe('archived')->and($r['matched_id'])->toBe(9);
|
|
});
|
|
|
|
it('приоритет активного над архивом', function () {
|
|
$out = classifier()->classify(
|
|
finds: [['id' => 1, 'name' => 'A', 'site_url' => 'a.ru', 'directory_urls' => []]],
|
|
existing: [
|
|
['id' => 8, 'box' => 'archived', 'name' => 'A', 'site_url' => 'a.ru', 'directory_urls' => []],
|
|
['id' => 9, 'box' => 'field', 'name' => 'A', 'site_url' => 'a.ru', 'directory_urls' => []],
|
|
],
|
|
);
|
|
$r = grp($out, 1);
|
|
expect($r['group'])->toBe('hidden')->and($r['matched_id'])->toBe(9);
|
|
});
|
|
|
|
it('без опознавалок находка всегда новая', function () {
|
|
$out = classifier()->classify(
|
|
finds: [['id' => 1, 'name' => 'Безымянный', 'site_url' => null, 'directory_urls' => []]],
|
|
existing: [['id' => 9, 'box' => 'field', 'name' => 'Безымянный', 'site_url' => null, 'directory_urls' => []]],
|
|
);
|
|
expect(grp($out, 1)['group'])->toBe('new');
|
|
});
|