seed(PricingTierSeeder::class); }); it('GET /api/admin/pricing-tiers returns active + scheduled sets', function () { $response = $this->getJson('/api/admin/pricing-tiers'); $response->assertOk(); expect($response->json('data.active'))->toHaveCount(7); }); it('POST creates 7 new tiers with auto effective_from = 1st of next month', function () { $payload = ['tiers' => [ ['tier_no' => 1, 'leads_in_tier' => 50, 'price_rub' => '600.00'], ['tier_no' => 2, 'leads_in_tier' => 150, 'price_rub' => '550.00'], ['tier_no' => 3, 'leads_in_tier' => 300, 'price_rub' => '500.00'], ['tier_no' => 4, 'leads_in_tier' => 700, 'price_rub' => '450.00'], ['tier_no' => 5, 'leads_in_tier' => 1500, 'price_rub' => '400.00'], ['tier_no' => 6, 'leads_in_tier' => 3000, 'price_rub' => '350.00'], ['tier_no' => 7, 'leads_in_tier' => null, 'price_rub' => '300.00'], ]]; $this->postJson('/api/admin/pricing-tiers', $payload)->assertCreated(); $expectedDate = now('Europe/Moscow')->startOfMonth()->addMonth()->toDateString(); $newTiers = PricingTier::where('effective_from', $expectedDate)->get(); expect($newTiers)->toHaveCount(7); expect($newTiers->where('tier_no', 1)->first()->price_per_lead_kopecks)->toBe(60000); expect($newTiers->where('tier_no', 7)->first()->leads_in_tier)->toBeNull(); }); it('POST validates: exactly 7 rows required', function () { $this->postJson('/api/admin/pricing-tiers', ['tiers' => [ ['tier_no' => 1, 'leads_in_tier' => 50, 'price_rub' => '600.00'], ]])->assertStatus(422); }); it('POST validates: tier_no must be unique 1..7', function () { $this->postJson('/api/admin/pricing-tiers', ['tiers' => [ ['tier_no' => 1, 'leads_in_tier' => 50, 'price_rub' => '600.00'], ['tier_no' => 1, 'leads_in_tier' => 150, 'price_rub' => '550.00'], ['tier_no' => 3, 'leads_in_tier' => 300, 'price_rub' => '500.00'], ['tier_no' => 4, 'leads_in_tier' => 700, 'price_rub' => '450.00'], ['tier_no' => 5, 'leads_in_tier' => 1500, 'price_rub' => '400.00'], ['tier_no' => 6, 'leads_in_tier' => 3000, 'price_rub' => '350.00'], ['tier_no' => 7, 'leads_in_tier' => null, 'price_rub' => '300.00'], ]])->assertStatus(422); }); it('POST validates: tier 7 leads_in_tier must be null', function () { $this->postJson('/api/admin/pricing-tiers', ['tiers' => [ ['tier_no' => 1, 'leads_in_tier' => 50, 'price_rub' => '600.00'], ['tier_no' => 2, 'leads_in_tier' => 150, 'price_rub' => '550.00'], ['tier_no' => 3, 'leads_in_tier' => 300, 'price_rub' => '500.00'], ['tier_no' => 4, 'leads_in_tier' => 700, 'price_rub' => '450.00'], ['tier_no' => 5, 'leads_in_tier' => 1500, 'price_rub' => '400.00'], ['tier_no' => 6, 'leads_in_tier' => 3000, 'price_rub' => '350.00'], ['tier_no' => 7, 'leads_in_tier' => 99999, 'price_rub' => '300.00'], ]])->assertStatus(422); }); it('POST validates: price_rub >= 0', function () { $this->postJson('/api/admin/pricing-tiers', ['tiers' => [ ['tier_no' => 1, 'leads_in_tier' => 50, 'price_rub' => '-1.00'], ['tier_no' => 2, 'leads_in_tier' => 150, 'price_rub' => '550.00'], ['tier_no' => 3, 'leads_in_tier' => 300, 'price_rub' => '500.00'], ['tier_no' => 4, 'leads_in_tier' => 700, 'price_rub' => '450.00'], ['tier_no' => 5, 'leads_in_tier' => 1500, 'price_rub' => '400.00'], ['tier_no' => 6, 'leads_in_tier' => 3000, 'price_rub' => '350.00'], ['tier_no' => 7, 'leads_in_tier' => null, 'price_rub' => '300.00'], ]])->assertStatus(422); }); it('DELETE /scheduled/{effective_from} removes future tiers only', function () { $futureDate = now('Europe/Moscow')->addMonth()->startOfMonth()->toDateString(); PricingTier::factory()->count(7)->sequence(fn ($s) => ['tier_no' => $s->index + 1]) ->create(['effective_from' => $futureDate, 'is_active' => true]); $this->deleteJson("/api/admin/pricing-tiers/scheduled/{$futureDate}")->assertOk(); expect(PricingTier::where('effective_from', $futureDate)->count())->toBe(0); expect(PricingTier::where('effective_from', '1970-01-01')->count())->toBe(7); }); it('writes audit-trail row in saas_admin_audit_log on POST', function () { $this->postJson('/api/admin/pricing-tiers', ['tiers' => [ ['tier_no' => 1, 'leads_in_tier' => 50, 'price_rub' => '600.00'], ['tier_no' => 2, 'leads_in_tier' => 150, 'price_rub' => '550.00'], ['tier_no' => 3, 'leads_in_tier' => 300, 'price_rub' => '500.00'], ['tier_no' => 4, 'leads_in_tier' => 700, 'price_rub' => '450.00'], ['tier_no' => 5, 'leads_in_tier' => 1500, 'price_rub' => '400.00'], ['tier_no' => 6, 'leads_in_tier' => 3000, 'price_rub' => '350.00'], ['tier_no' => 7, 'leads_in_tier' => null, 'price_rub' => '300.00'], ]])->assertCreated(); $log = DB::table('saas_admin_audit_log') ->where('action', 'pricing_tiers.create_scheduled')->first(); expect($log)->not->toBeNull(); });