Files
portal/app/tests/Feature/Autopodbor/AutopodborRenamePropagationTest.php
T
Дмитрий 928561bd12 fix(autopodbor): переименование конкурента тянет имена проектов + слияние не роняет карточку в предложения
Две починки в «Конкурентном поле» + превью выжившего в окне склейки:

1. Переименование конкурента (PATCH competitors/{id}) не обновляло имена
   уже созданных проектов — они носят имя-снимок конкурента. Теперь при
   смене имени проекты синхронизируются (syncNamesForCompetitor): меняется
   только отображаемое имя, signal_identifier поставщика не трогаем.

2. Слияние дублей не пересматривало ящик выжившего. Если выжившим по
   возрасту/деньгам оказывалось предложение, объединённая карточка уезжала
   в «Предложения», даже когда одна из склеиваемых была в «Поле». Теперь
   объединённая получает сильнейший ящик (поле > предложение > архив) —
   только повышаем, никогда не понижаем.

3. Окно «Почистить поле» показывает, какая карточка останется после склейки
   (survivor во duplicateGroups) — не затираем имя вслепую.

Тесты: весь блок автоподбора зелёный (426). Larastan в этой рабочей копии
падает без вывода на любом файле — среда, не код.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-05 13:29:16 +03:00

68 lines
3.8 KiB
PHP

<?php
declare(strict_types=1);
use App\Models\AutopodborCompetitor;
use App\Models\AutopodborRun;
use App\Models\AutopodborSource;
use App\Models\Project;
use App\Models\Tenant;
use App\Models\User;
use App\Services\Autopodbor\AutopodborProjectCreator;
use Illuminate\Foundation\Testing\DatabaseTransactions;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Queue;
use Tests\Concerns\SharesSupplierPdo;
uses(DatabaseTransactions::class, SharesSupplierPdo::class);
it('PATCH competitors/{id} — переименование конкурента переименовывает его проект', function () {
Queue::fake();
$tenant = Tenant::factory()->create(['balance_rub' => '500000.00']);
$user = User::factory()->create(['tenant_id' => $tenant->id]);
DB::statement('SET app.current_tenant_id = '.$tenant->id);
$run = AutopodborRun::create(['tenant_id' => $tenant->id, 'kind' => 'search', 'status' => 'done', 'region_code' => 16]);
$comp = AutopodborCompetitor::create(['tenant_id' => $tenant->id, 'name' => 'Сибирская Строительная', 'box' => 'field', 'dedup_key' => 'sib']);
$src = AutopodborSource::create(['tenant_id' => $tenant->id, 'competitor_id' => $comp->id, 'study_run_id' => $run->id, 'signal_type' => 'site', 'identifier' => 'sibsk.ru', 'box' => 'field', 'dedup_key' => 'site:sibsk.ru']);
app(AutopodborProjectCreator::class)->createFromSources($tenant->id, [$src->id], [
'regions' => [16], 'daily_limit_target' => 20, 'delivery_days_mask' => 127,
], launch: false);
$project = $src->fresh()->project;
expect($project->name)->toBe('Сибирская Строительная'); // имя-снимок при создании
$this->actingAs($user)->patchJson("/api/autopodbor/competitors/{$comp->id}", [
'name' => 'Сибиряк',
])->assertOk();
expect($project->fresh()->name)->toBe('Сибиряк'); // проект следует за новым именем конкурента
});
it('PATCH competitors/{id} — при двух проектах имена различаются источником после переименования', function () {
Queue::fake();
$tenant = Tenant::factory()->create(['balance_rub' => '500000.00']);
$user = User::factory()->create(['tenant_id' => $tenant->id]);
DB::statement('SET app.current_tenant_id = '.$tenant->id);
$run = AutopodborRun::create(['tenant_id' => $tenant->id, 'kind' => 'search', 'status' => 'done', 'region_code' => 16]);
$comp = AutopodborCompetitor::create(['tenant_id' => $tenant->id, 'name' => 'Старое Имя', 'box' => 'field', 'dedup_key' => 'old']);
$s1 = AutopodborSource::create(['tenant_id' => $tenant->id, 'competitor_id' => $comp->id, 'study_run_id' => $run->id, 'signal_type' => 'site', 'identifier' => 'a.ru', 'box' => 'field', 'dedup_key' => 'site:a.ru']);
$s2 = AutopodborSource::create(['tenant_id' => $tenant->id, 'competitor_id' => $comp->id, 'study_run_id' => $run->id, 'signal_type' => 'site', 'identifier' => 'b.ru', 'box' => 'field', 'dedup_key' => 'site:b.ru']);
app(AutopodborProjectCreator::class)->createFromSources($tenant->id, [$s1->id, $s2->id], [
'regions' => [16], 'daily_limit_target' => 20, 'delivery_days_mask' => 127,
], launch: false);
$this->actingAs($user)->patchJson("/api/autopodbor/competitors/{$comp->id}", [
'name' => 'Новое Имя',
])->assertOk();
$names = Project::where('tenant_id', $tenant->id)->pluck('name')->all();
expect($names)->toContain('Новое Имя')
->and(collect($names)->contains(fn ($n) => str_contains((string) $n, 'Новое Имя · ')))->toBeTrue()
->and(collect($names)->unique()->count())->toBe(2)
->and(collect($names)->contains(fn ($n) => str_contains((string) $n, 'Старое')))->toBeFalse();
});