seed(PricingTierSeeder::class); // Set global tenant context (bypass RLS for seeding/reading) DB::statement("SELECT set_config('app.current_tenant_id', '0', true)"); }); /** * Task 3 Step 1 — SnapshotForge::rebuild() creates a snapshot row * for the active date for an eligible project. */ it('rebuild() creates a project_routing_snapshots row for the active date', function (): void { // Arrange: tenant with positive balance (required by snapshot:rebuild eligibility) $tenant = Tenant::factory()->create([ 'balance_rub' => '500.00', 'frozen_by_balance_at' => null, ]); // Arrange: active project with call signal (required by snapshot:rebuild // INSERT: signal_type NOT NULL CHECK IN ('call','site','sms')) $project = Project::factory()->create([ 'tenant_id' => $tenant->id, 'is_active' => true, 'signal_type' => 'call', 'signal_identifier' => '79161234567', 'daily_limit_target' => 10, 'delivery_days_mask' => 127, // all 7 days 'preflight_blocked_at' => null, ]); // Act: rebuild snapshots for the active date SnapshotForge::rebuild(); // Assert: a snapshot row exists for the active date and this project. // Use pgsql_supplier (BYPASSRLS) so we can see the row regardless of // the RLS tenant context set above — mirrors how LeadRouter queries. $activeDate = SnapshotForge::activeDate(); $row = DB::connection('pgsql_supplier') ->table('project_routing_snapshots') ->where('snapshot_date', $activeDate) ->where('project_id', $project->id) ->first(); expect($row)->not->toBeNull('SnapshotForge::rebuild() should insert a row for the active date'); expect((int) $row->project_id)->toBe($project->id); expect((string) $row->snapshot_date)->toStartWith($activeDate); })->group('imitation');