toBeTrue(); expect(Schema::hasColumns('project_routing_snapshots', [ 'snapshot_date', 'project_id', 'tenant_id', 'daily_limit', 'delivery_days_mask', 'regions', 'signal_type', 'signal_identifier', 'sms_senders', 'sms_keyword', 'expected_volume', 'delivered_count', 'created_at', ]))->toBeTrue(); }); it('rejects negative daily_limit / expected_volume / delivered_count', function () { DB::table('project_routing_snapshots')->insert([ 'snapshot_date' => '2026-05-28', 'project_id' => 1, 'tenant_id' => 1, 'daily_limit' => -1, // CHECK violation 'delivery_days_mask' => 0, 'regions' => '{}', 'signal_type' => 'call', 'expected_volume' => 0, 'delivered_count' => 0, 'created_at' => now(), ]); })->throws(\Illuminate\Database\QueryException::class); it('enforces composite PK (snapshot_date, project_id)', function () { $tenant = \App\Models\Tenant::factory()->create(); $project = \App\Models\Project::factory()->for($tenant)->create(); DB::table('project_routing_snapshots')->insert([ 'snapshot_date' => '2026-05-28', 'project_id' => $project->id, 'tenant_id' => $tenant->id, 'daily_limit' => 10, 'delivery_days_mask' => 127, 'regions' => '{}', 'signal_type' => 'call', 'expected_volume' => 10, 'delivered_count' => 0, 'created_at' => now(), ]); // Дубль — должен упасть на PK violation expect(fn () => DB::table('project_routing_snapshots')->insert([ 'snapshot_date' => '2026-05-28', 'project_id' => $project->id, 'tenant_id' => $tenant->id, 'daily_limit' => 20, 'delivery_days_mask' => 127, 'regions' => '{}', 'signal_type' => 'call', 'expected_volume' => 20, 'delivered_count' => 0, 'created_at' => now(), ]))->toThrow(\Illuminate\Database\QueryException::class); });