Files
portal/app/tests/Feature/Console/BackfillRootSupplierLinksCommandTest.php
T
Дмитрий 50b789b69f feat(supplier): артизан-команда supplier:backfill-root-links
Однократный back-fill для уже существующих проектов: для каждого
site-проекта с identifier-субдоменом добавляет линки к корневым sp,
если они есть в supplier_projects. Идемпотентна (явная проверка
existence перед insert). --dry-run выводит ожидаемый эффект без записи.

3 feature-теста: add root link / idempotency / dry-run no-write.

Spec: docs/superpowers/specs/2026-05-22-root-domain-auto-link-design.md §4.3

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-22 12:22:17 +03:00

115 lines
4.4 KiB
PHP

<?php
declare(strict_types=1);
use App\Models\Project;
use App\Models\SupplierProject;
use App\Models\Tenant;
use Illuminate\Foundation\Testing\DatabaseTransactions;
use Illuminate\Support\Facades\Artisan;
use Illuminate\Support\Facades\DB;
use Tests\Concerns\SharesSupplierPdo;
uses(DatabaseTransactions::class, SharesSupplierPdo::class);
it('backfill: добавляет root-link для проекта-субдомена с уже-существующими линками', function () {
$tenant = Tenant::factory()->create();
$project = Project::factory()->create([
'tenant_id' => $tenant->id,
'signal_type' => 'site',
'signal_identifier' => 'krasnoyarsk.carmoney.ru',
]);
$subdomainSp = SupplierProject::create([
'platform' => 'B2',
'signal_type' => 'site',
'unique_key' => 'krasnoyarsk.carmoney.ru',
'supplier_external_id' => 'ext-sub',
'current_limit' => 100,
'sync_status' => 'ok',
]);
$rootSp = SupplierProject::create([
'platform' => 'B2',
'signal_type' => 'site',
'unique_key' => 'carmoney.ru',
'supplier_external_id' => 'ext-root',
'current_limit' => 100,
'sync_status' => 'ok',
]);
DB::connection('pgsql_supplier')->table('project_supplier_links')->insert([
'project_id' => $project->id,
'supplier_project_id' => $subdomainSp->id,
'platform' => 'B2',
'subject_code' => null,
]);
$exitCode = Artisan::call('supplier:backfill-root-links');
expect($exitCode)->toBe(0);
expect(
DB::connection('pgsql_supplier')->table('project_supplier_links')
->where('project_id', $project->id)
->where('supplier_project_id', $rootSp->id)
->exists()
)->toBeTrue();
});
it('backfill: idempotent — повторный прогон ничего не добавляет', function () {
$tenant = Tenant::factory()->create();
$project = Project::factory()->create([
'tenant_id' => $tenant->id,
'signal_type' => 'site',
'signal_identifier' => 'client.carmoney.ru',
]);
$subSp = SupplierProject::create([
'platform' => 'B2', 'signal_type' => 'site', 'unique_key' => 'client.carmoney.ru',
'supplier_external_id' => 'ext1', 'current_limit' => 100, 'sync_status' => 'ok',
]);
SupplierProject::create([
'platform' => 'B2', 'signal_type' => 'site', 'unique_key' => 'carmoney.ru',
'supplier_external_id' => 'ext2', 'current_limit' => 100, 'sync_status' => 'ok',
]);
DB::connection('pgsql_supplier')->table('project_supplier_links')->insert([
'project_id' => $project->id, 'supplier_project_id' => $subSp->id,
'platform' => 'B2', 'subject_code' => null,
]);
Artisan::call('supplier:backfill-root-links');
$afterFirst = DB::connection('pgsql_supplier')->table('project_supplier_links')
->where('project_id', $project->id)->count();
Artisan::call('supplier:backfill-root-links');
$afterSecond = DB::connection('pgsql_supplier')->table('project_supplier_links')
->where('project_id', $project->id)->count();
expect($afterFirst)->toBe(2);
expect($afterSecond)->toBe(2);
});
it('backfill --dry-run: ничего не пишет в БД', function () {
$tenant = Tenant::factory()->create();
$project = Project::factory()->create([
'tenant_id' => $tenant->id,
'signal_type' => 'site',
'signal_identifier' => 'next.vashinvestor.ru',
]);
$subSp = SupplierProject::create([
'platform' => 'B2', 'signal_type' => 'site', 'unique_key' => 'next.vashinvestor.ru',
'supplier_external_id' => 'extn1', 'current_limit' => 100, 'sync_status' => 'ok',
]);
SupplierProject::create([
'platform' => 'B2', 'signal_type' => 'site', 'unique_key' => 'vashinvestor.ru',
'supplier_external_id' => 'extn2', 'current_limit' => 100, 'sync_status' => 'ok',
]);
DB::connection('pgsql_supplier')->table('project_supplier_links')->insert([
'project_id' => $project->id, 'supplier_project_id' => $subSp->id,
'platform' => 'B2', 'subject_code' => null,
]);
Artisan::call('supplier:backfill-root-links', ['--dry-run' => true]);
$count = DB::connection('pgsql_supplier')->table('project_supplier_links')
->where('project_id', $project->id)->count();
expect($count)->toBe(1);
});