Files
portal/app/tests/Support/Imitation/ImitationTestCase.php
T
Дмитрий 4dfcde99ba fix(imitation): correct seedPhoneRange columns + import_id FK (F1)
ImitationTestCase::seedPhoneRange used non-existent columns (range_from/range_to/region_name) and omitted the required import_id FK, so every Россвязь-branch test that called it failed. Now seeds a phone_ranges_imports anchor row and inserts phone_ranges with the real columns (def_code/from_num/to_num/operator/region/subject_code/imported_at/import_id), mirroring the verified RossvyazPrefixLookup parsing. Found during Task 5.
2026-06-04 03:54:22 +03:00

119 lines
4.7 KiB
PHP

<?php
declare(strict_types=1);
namespace Tests\Support\Imitation;
use Database\Seeders\PricingTierSeeder;
use Illuminate\Foundation\Testing\DatabaseTransactions;
use Illuminate\Support\Facades\DB;
use Tests\Concerns\SharesSupplierPdo;
use Tests\TestCase;
/**
* Base test case for Phase 1 imitation harness tests.
*
* Seeds reference data (pricing_tiers, suppliers) once per test within a
* database transaction so every test starts from a clean, known state.
*
* Usage:
* Extend this class (PHPUnit-style) or include the trait equivalents
* in Pest tests. Pest tests should prefer:
*
* uses(DatabaseTransactions::class, SharesSupplierPdo::class);
* beforeEach(fn () => (new ImitationTestCase())->seedReferenceData());
*
* Schema dependencies (exact columns verified against db/schema.sql):
* pricing_tiers: id, tier_no (1..7), leads_in_tier, price_per_lead_kopecks,
* is_active, effective_from, created_at, updated_at
* suppliers: id, code, name, accepts_types (varchar[]), cost_rub,
* channel, quality_score, is_active, sort_order, created_at
*
* Note: suppliers (b1/b2/b3/direct) are seeded via the initial schema
* migration and delta-migrations — they are expected to already exist in
* the test database. This case does NOT re-seed suppliers; it only verifies
* that at least one supplier row with code='b1' is present and seeds
* pricing_tiers via PricingTierSeeder.
*
* phone_ranges are NOT seeded globally. Tests that exercise the region-
* resolution cascade (Россвязь lookup) should call seedPhoneRange() directly
* for the specific range their scenario requires.
*
* Task 0.5 — Phase 1 Portal Client Imitation Harness.
* Spec: docs/superpowers/specs/2026-06-03-portal-client-imitation-phase1-design.md
*/
abstract class ImitationTestCase extends TestCase
{
use DatabaseTransactions;
use SharesSupplierPdo;
protected function setUp(): void
{
parent::setUp();
$this->seedReferenceData();
}
/**
* Seed shared reference data required by all imitation tests.
*
* Called automatically from setUp(). Safe to call multiple times within a
* transaction (PricingTierSeeder uses updateOrCreate; supplier check is
* read-only).
*/
public function seedReferenceData(): void
{
// Pricing tiers — required by LedgerService::chargeForDelivery.
// PricingTierSeeder uses updateOrCreate so it is safe to call within
// a DatabaseTransactions-wrapped test.
$this->seed(PricingTierSeeder::class);
// Tenant context: global bypass to allow cross-tenant reads during seeding.
DB::statement("SELECT set_config('app.current_tenant_id', '0', true)");
}
/**
* Seed a single phone range for Россвязь prefix lookup tests.
*
* Only call this when your specific test scenario exercises the Россвязь
* branch of LeadRegionResolver (e.g. DaData degradation tests).
*
* @param string $defCode DEF-code prefix (e.g. '999').
* @param string $from Lower bound of number range (e.g. '0000000').
* @param string $to Upper bound of number range (e.g. '0099999').
* @param int $subjectCode Subject code (1..89, порядковый, НЕ ГИБДД).
* Use App\Support\RussianRegions::nameToCode() for lookup.
*/
protected function seedPhoneRange(
int $defCode,
int $from,
int $to,
int $subjectCode,
): void {
// Anchor phone_ranges_imports row first — phone_ranges.import_id is a
// required FK (migration 2026_05_31_100000). F1 fix: the previous version
// used non-existent columns (range_from/range_to/region_name) and omitted
// import_id, so every Россвязь-branch test that called it failed at runtime.
$importId = DB::table('phone_ranges_imports')->insertGetId([
'imported_at' => now(),
'source_url' => 'test://rossvyaz',
'rows_inserted' => 1,
'rows_updated' => 0,
'checksum_sha256' => str_repeat('0', 64),
'status' => 'completed',
'completed_at' => now(),
]);
DB::table('phone_ranges')->insert([
'def_code' => $defCode,
'from_num' => $from,
'to_num' => $to,
'operator' => 'test-operator',
'region' => \App\Support\RussianRegions::CODE_TO_NAME[$subjectCode] ?? 'test-region',
'region_normalized' => null,
'subject_code' => $subjectCode,
'imported_at' => now(),
'import_id' => $importId,
]);
}
}