Files
portal/app/tests/Feature/Models/ProjectExtensionsTest.php
T

107 lines
4.0 KiB
PHP
Raw Normal View History

<?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\DB;
uses(DatabaseTransactions::class);
test('Project has signal_type, signal_identifier in fillable', function () {
$tenant = Tenant::factory()->create();
DB::statement("SET LOCAL app.current_tenant_id = '{$tenant->id}'");
$p = Project::factory()->for($tenant)->asSiteSignal('example.com')->create();
expect($p->signal_type)->toBe('site');
expect($p->signal_identifier)->toBe('example.com');
});
test('Project casts sms_senders as array + sms_keyword stored', function () {
$tenant = Tenant::factory()->create();
DB::statement("SET LOCAL app.current_tenant_id = '{$tenant->id}'");
$p = Project::factory()
->for($tenant)
->asSmsSignal(['TINKOFF', 'SBERBANK'], 'ипотека')
->create();
expect($p->fresh()->sms_senders)->toBe(['TINKOFF', 'SBERBANK']);
expect($p->fresh()->sms_keyword)->toBe('ипотека');
});
test('Project SMS without keyword stores null keyword', function () {
$tenant = Tenant::factory()->create();
DB::statement("SET LOCAL app.current_tenant_id = '{$tenant->id}'");
$p = Project::factory()
->for($tenant)
->asSmsSignal(['TINKOFF'], null)
->create();
expect($p->fresh()->sms_keyword)->toBeNull();
expect($p->fresh()->sms_senders)->toBe(['TINKOFF']);
});
test('Project has supplierB1/B2/B3 relations', function () {
$tenant = Tenant::factory()->create();
DB::statement("SET LOCAL app.current_tenant_id = '{$tenant->id}'");
$sp = SupplierProject::factory()->create(['platform' => 'B1']);
$p = Project::factory()->for($tenant)->create(['supplier_b1_project_id' => $sp->id]);
expect($p->supplierB1)->toBeInstanceOf(SupplierProject::class);
expect($p->supplierB1->id)->toBe($sp->id);
expect($p->supplierB2)->toBeNull();
expect($p->supplierB3)->toBeNull();
});
test('Project scopeActiveOnDay returns only projects with today bit set in delivery_days_mask', function () {
$tenant = Tenant::factory()->create();
DB::statement("SET LOCAL app.current_tenant_id = '{$tenant->id}'");
// Все 7 дней (битмаска 0b1111111 = 127)
Project::factory()->for($tenant)->create([
'is_active' => true,
'delivery_days_mask' => 0b1111111,
]);
// Только Сб+Вс (биты 5,6 = 0b1100000 = 96)
Project::factory()->for($tenant)->create([
'is_active' => true,
'delivery_days_mask' => 0b1100000,
]);
// Неактивный — не попадает независимо от маски
Project::factory()->for($tenant)->create([
'is_active' => false,
'delivery_days_mask' => 0b1111111,
]);
$todayDow = (int) now()->dayOfWeekIso;
// Проект на все дни должен пройти на любой день
$count = Project::activeOnDay($todayDow)->count();
expect($count)->toBeGreaterThanOrEqual(1);
// Понедельник (ISO=1, bit 0): проходит только проект на все дни
expect(Project::activeOnDay(1)->count())->toBe(1);
// Суббота (ISO=6, bit 5): проходят оба активных
expect(Project::activeOnDay(6)->count())->toBe(2);
});
test('Project scopeForSignal filters by (signal_type, signal_identifier)', function () {
$tenant = Tenant::factory()->create();
DB::statement("SET LOCAL app.current_tenant_id = '{$tenant->id}'");
Project::factory()->for($tenant)->asSiteSignal('a.com')->create();
Project::factory()->for($tenant)->asSiteSignal('b.com')->create();
Project::factory()->for($tenant)->asCallSignal('79991234567')->create();
expect(Project::forSignal('site', 'a.com')->count())->toBe(1);
expect(Project::forSignal('site', 'b.com')->count())->toBe(1);
expect(Project::forSignal('call', '79991234567')->count())->toBe(1);
expect(Project::forSignal('site', 'nonexistent.com')->count())->toBe(0);
});