62aa55f033
- app/Models/SupplierProject.php — fillable + casts (jsonb arrays + datetime) + scopes: active() (inactive_since IS NULL), staleSince(N days), forSignal(signal_type, unique_key) - database/factories/SupplierProjectFactory.php — корректно учитывает chk_supplier_projects_b1_not_for_sms (B1 не порождает SMS-проекты) - tests/Feature/Models/SupplierProjectTest.php — 6 тестов: factory, array casts (workdays + regions), scopeActive, scopeStaleSince, scopeForSignal (3 платформы на один домен — UNIQUE (platform,unique_key)) ide-helper:models -W -M -N перегенерил docblocks для 4 существующих моделей (SaasAdminAuditLog, SystemSetting, UserRecoveryCode, ImpersonationToken) — синхронизировал @property после schema v8.16. Pest: 451 / 449 passed / 2 skipped (было 443+6 новых от Task 6 = 449). Larastan: 0 errors. Pint: passed. Spec: §2.2 Plan: Task 6 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
60 lines
2.6 KiB
PHP
60 lines
2.6 KiB
PHP
<?php
|
||
|
||
declare(strict_types=1);
|
||
|
||
use App\Models\SupplierProject;
|
||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||
|
||
uses(DatabaseTransactions::class);
|
||
|
||
test('SupplierProject can be created via factory', function () {
|
||
$sp = SupplierProject::factory()->create();
|
||
expect($sp->id)->toBeInt()->toBeGreaterThan(0);
|
||
expect($sp->platform)->toBeIn(['B1', 'B2', 'B3']);
|
||
expect($sp->signal_type)->toBeIn(['site', 'call', 'sms']);
|
||
});
|
||
|
||
test('SupplierProject casts current_workdays as array', function () {
|
||
$sp = SupplierProject::factory()->create([
|
||
'current_workdays' => [1, 2, 3, 4, 5],
|
||
]);
|
||
|
||
expect($sp->fresh()->current_workdays)->toBe([1, 2, 3, 4, 5]);
|
||
});
|
||
|
||
test('SupplierProject casts current_regions as array', function () {
|
||
$sp = SupplierProject::factory()->create([
|
||
'current_regions' => ['77', '78'],
|
||
]);
|
||
|
||
expect($sp->fresh()->current_regions)->toBe(['77', '78']);
|
||
});
|
||
|
||
test('SupplierProject scopeActive returns only rows with inactive_since IS NULL', function () {
|
||
SupplierProject::factory()->create(['inactive_since' => null]);
|
||
SupplierProject::factory()->create(['inactive_since' => now()->subDays(10)]);
|
||
|
||
expect(SupplierProject::active()->count())->toBe(1);
|
||
});
|
||
|
||
test('SupplierProject scopeStaleSince returns rows inactive longer than N days', function () {
|
||
SupplierProject::factory()->create(['inactive_since' => now()->subDays(200)]);
|
||
SupplierProject::factory()->create(['inactive_since' => now()->subDays(100)]);
|
||
SupplierProject::factory()->create(['inactive_since' => null]);
|
||
|
||
expect(SupplierProject::staleSince(180)->count())->toBe(1);
|
||
});
|
||
|
||
test('SupplierProject scopeForSignal filters by (signal_type, unique_key)', function () {
|
||
// Один домен на трёх платформах — UNIQUE (platform, unique_key) допускает.
|
||
SupplierProject::factory()->create(['signal_type' => 'site', 'unique_key' => 'a.com', 'platform' => 'B1']);
|
||
SupplierProject::factory()->create(['signal_type' => 'site', 'unique_key' => 'a.com', 'platform' => 'B2']);
|
||
SupplierProject::factory()->create(['signal_type' => 'site', 'unique_key' => 'a.com', 'platform' => 'B3']);
|
||
// Другой источник — не должен попасть в результат.
|
||
SupplierProject::factory()->create(['signal_type' => 'site', 'unique_key' => 'b.com', 'platform' => 'B1']);
|
||
// Call-сигнал с unique_key=телефон — также не должен попасть.
|
||
SupplierProject::factory()->create(['signal_type' => 'call', 'unique_key' => '79991234567', 'platform' => 'B1']);
|
||
|
||
expect(SupplierProject::forSignal('site', 'a.com')->count())->toBe(3);
|
||
});
|